libpldm: Migrate to subproject

Organize files in libpldm to make it a subproject

In the current state, libpldm is not readily consumable
as a subproject.This commit does all the necessary re-organisation
of the source code to make it work as a subproject.

There are no .c/.h files changes in this commit, only meson
changes and re-organising the code structure.

Signed-off-by: Manojkiran Eda <manojkiran.eda@gmail.com>
Change-Id: I20a71c0c972b1fd81fb359d604433618799102c6
diff --git a/include/libpldm/base.h b/include/libpldm/base.h
new file mode 100644
index 0000000..be1e355
--- /dev/null
+++ b/include/libpldm/base.h
@@ -0,0 +1,553 @@
+#ifndef BASE_H
+#define BASE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <asm/byteorder.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "pldm_types.h"
+
+/** @brief PLDM Types
+ */
+enum pldm_supported_types {
+	PLDM_BASE = 0x00,
+	PLDM_PLATFORM = 0x02,
+	PLDM_BIOS = 0x03,
+	PLDM_FRU = 0x04,
+	PLDM_FWUP = 0x05,
+	PLDM_OEM = 0x3F,
+};
+
+/** @brief PLDM Commands
+ */
+enum pldm_supported_commands {
+	PLDM_GET_TID = 0x2,
+	PLDM_GET_PLDM_VERSION = 0x3,
+	PLDM_GET_PLDM_TYPES = 0x4,
+	PLDM_GET_PLDM_COMMANDS = 0x5,
+	PLDM_MULTIPART_RECEIVE = 0x9,
+};
+
+/** @brief PLDM base codes
+ */
+enum pldm_completion_codes {
+	PLDM_SUCCESS = 0x00,
+	PLDM_ERROR = 0x01,
+	PLDM_ERROR_INVALID_DATA = 0x02,
+	PLDM_ERROR_INVALID_LENGTH = 0x03,
+	PLDM_ERROR_NOT_READY = 0x04,
+	PLDM_ERROR_UNSUPPORTED_PLDM_CMD = 0x05,
+	PLDM_ERROR_INVALID_PLDM_TYPE = 0x20,
+	PLDM_INVALID_TRANSFER_OPERATION_FLAG = 0x21
+};
+
+enum transfer_op_flag {
+	PLDM_GET_NEXTPART = 0,
+	PLDM_GET_FIRSTPART = 1,
+};
+
+enum transfer_multipart_op_flag {
+	PLDM_XFER_FIRST_PART = 0,
+	PLDM_XFER_NEXT_PART = 1,
+	PLDM_XFER_ABORT = 2,
+	PLDM_XFER_COMPLETE = 3,
+	PLDM_XFER_CURRENT_PART = 4,
+};
+
+enum transfer_resp_flag {
+	PLDM_START = 0x01,
+	PLDM_MIDDLE = 0x02,
+	PLDM_END = 0x04,
+	PLDM_START_AND_END = 0x05,
+};
+
+/** @brief PLDM transport protocol type
+ */
+enum pldm_transport_protocol_type {
+	PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP = 0x00,
+	PLDM_TRANSPORT_PROTOCOL_TYPE_OEM = 0xFF,
+};
+
+/** @enum MessageType
+ *
+ *  The different message types supported by the PLDM specification.
+ */
+typedef enum {
+	PLDM_RESPONSE,		   //!< PLDM response
+	PLDM_REQUEST,		   //!< PLDM request
+	PLDM_RESERVED,		   //!< Reserved
+	PLDM_ASYNC_REQUEST_NOTIFY, //!< Unacknowledged PLDM request messages
+} MessageType;
+
+#define PLDM_INSTANCE_MAX 31
+#define PLDM_MAX_TYPES 64
+#define PLDM_MAX_CMDS_PER_TYPE 256
+
+/* Message payload lengths */
+#define PLDM_GET_COMMANDS_REQ_BYTES 5
+#define PLDM_GET_VERSION_REQ_BYTES 6
+
+/* Response lengths are inclusive of completion code */
+#define PLDM_GET_TYPES_RESP_BYTES 9
+#define PLDM_GET_TID_RESP_BYTES 2
+#define PLDM_GET_COMMANDS_RESP_BYTES 33
+/* Response data has only one version and does not contain the checksum */
+#define PLDM_GET_VERSION_RESP_BYTES 10
+#define PLDM_MULTIPART_RECEIVE_REQ_BYTES 18
+
+#define PLDM_VERSION_0 0
+#define PLDM_CURRENT_VERSION PLDM_VERSION_0
+
+#define PLDM_TIMESTAMP104_SIZE 13
+
+/** @struct pldm_msg_hdr
+ *
+ * Structure representing PLDM message header fields
+ */
+struct pldm_msg_hdr {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+	uint8_t instance_id : 5; //!< Instance ID
+	uint8_t reserved : 1;	 //!< Reserved
+	uint8_t datagram : 1;	 //!< Datagram bit
+	uint8_t request : 1;	 //!< Request bit
+#elif defined(__BIG_ENDIAN_BITFIELD)
+	uint8_t request : 1;	 //!< Request bit
+	uint8_t datagram : 1;	 //!< Datagram bit
+	uint8_t reserved : 1;	 //!< Reserved
+	uint8_t instance_id : 5; //!< Instance ID
+#endif
+
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+	uint8_t type : 6;	//!< PLDM type
+	uint8_t header_ver : 2; //!< Header version
+#elif defined(__BIG_ENDIAN_BITFIELD)
+	uint8_t header_ver : 2;	 //!< Header version
+	uint8_t type : 6;	 //!< PLDM type
+#endif
+	uint8_t command; //!< PLDM command code
+} __attribute__((packed));
+
+// Macros for byte-swapping variables in-place
+#define HTOLE32(X) (X = htole32(X))
+#define HTOLE16(X) (X = htole16(X))
+#define LE32TOH(X) (X = le32toh(X))
+#define LE16TOH(X) (X = le16toh(X))
+
+/** @struct pldm_msg
+ *
+ * Structure representing PLDM message
+ */
+struct pldm_msg {
+	struct pldm_msg_hdr hdr; //!< PLDM message header
+	uint8_t payload[1]; //!< &payload[0] is the beginning of the payload
+} __attribute__((packed));
+
+/** @struct pldm_header_info
+ *
+ *  The information needed to prepare PLDM header and this is passed to the
+ *  pack_pldm_header and unpack_pldm_header API.
+ */
+struct pldm_header_info {
+	MessageType msg_type;	 //!< PLDM message type
+	uint8_t instance;	 //!< PLDM instance id
+	uint8_t pldm_type;	 //!< PLDM type
+	uint8_t command;	 //!< PLDM command code
+	uint8_t completion_code; //!< PLDM completion code, applies for response
+};
+
+/** @struct pldm_get_types_resp
+ *
+ *  Structure representing PLDM get types response.
+ */
+struct pldm_get_types_resp {
+	uint8_t completion_code; //!< completion code
+	bitfield8_t types[8]; //!< each bit represents whether a given PLDM Type
+			      //!< is supported
+} __attribute__((packed));
+
+/** @struct pldm_get_commands_req
+ *
+ *  Structure representing PLDM get commands request.
+ */
+struct pldm_get_commands_req {
+	uint8_t type;	 //!< PLDM Type for which command support information is
+			 //!< being requested
+	ver32_t version; //!< version for the specified PLDM Type
+} __attribute__((packed));
+
+/** @struct pldm_get_commands_resp
+ *
+ *  Structure representing PLDM get commands response.
+ */
+struct pldm_get_commands_resp {
+	uint8_t completion_code;  //!< completion code
+	bitfield8_t commands[32]; //!< each bit represents whether a given PLDM
+				  //!< command is supported
+} __attribute__((packed));
+
+/** @struct pldm_get_version_req
+ *
+ *  Structure representing PLDM get version request.
+ */
+struct pldm_get_version_req {
+	uint32_t
+	    transfer_handle; //!< handle to identify PLDM version data transfer
+	uint8_t transfer_opflag; //!< PLDM GetVersion operation flag
+	uint8_t type; //!< PLDM Type for which version information is being
+		      //!< requested
+} __attribute__((packed));
+
+/** @struct pldm_get_version_resp
+ *
+ *  Structure representing PLDM get version response.
+ */
+
+struct pldm_get_version_resp {
+	uint8_t completion_code;       //!< completion code
+	uint32_t next_transfer_handle; //!< next portion of PLDM version data
+				       //!< transfer
+	uint8_t transfer_flag;	       //!< PLDM GetVersion transfer flag
+	uint8_t version_data[1];       //!< PLDM GetVersion version field
+} __attribute__((packed));
+
+/** @struct pldm_get_tid_resp
+ *
+ *  Structure representing PLDM get tid response.
+ */
+
+struct pldm_get_tid_resp {
+	uint8_t completion_code; //!< completion code
+	uint8_t tid;		 //!< PLDM GetTID TID field
+} __attribute__((packed));
+
+/** @struct pldm_multipart_receive_req
+ *
+ * Structure representing PLDM multipart receive request.
+ */
+struct pldm_multipart_receive_req {
+	uint8_t pldm_type;	  //!< PLDM Type for the MultipartReceive
+				  //!< command.
+	uint8_t transfer_opflag;  //!< PLDM MultipartReceive operation flag.
+	uint32_t transfer_ctx;	  //!< Protocol-specifc context for this
+				  //!< transfer.
+	uint32_t transfer_handle; //!< handle to identify the part of data to be
+				  //!< received.
+	uint32_t section_offset;  //!< The start offset for the requested
+				  //!< section.
+	uint32_t section_length;  //!< The length (in bytes) of the section
+				  //!< requested.
+} __attribute__((packed));
+/**
+ * @brief Populate the PLDM message with the PLDM header.The caller of this API
+ *        allocates buffer for the PLDM header when forming the PLDM message.
+ *        The buffer is passed to this API to pack the PLDM header.
+ *
+ * @param[in] hdr - Pointer to the PLDM header information
+ * @param[out] msg - Pointer to PLDM message header
+ *
+ * @return 0 on success, otherwise PLDM error codes.
+ * @note   Caller is responsible for alloc and dealloc of msg
+ *         and hdr params
+ */
+uint8_t pack_pldm_header(const struct pldm_header_info *hdr,
+			 struct pldm_msg_hdr *msg);
+
+/**
+ * @brief Unpack the PLDM header from the PLDM message.
+ *
+ * @param[in] msg - Pointer to the PLDM message header
+ * @param[out] hdr - Pointer to the PLDM header information
+ *
+ * @return 0 on success, otherwise PLDM error codes.
+ * @note   Caller is responsible for alloc and dealloc of msg
+ *         and hdr params
+ */
+uint8_t unpack_pldm_header(const struct pldm_msg_hdr *msg,
+			   struct pldm_header_info *hdr);
+
+/* Requester */
+
+/* GetPLDMTypes */
+
+/** @brief Create a PLDM request message for GetPLDMTypes
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in,out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_get_types_req(uint8_t instance_id, struct pldm_msg *msg);
+
+/** @brief Decode a GetPLDMTypes response message
+ *
+ *  Note:
+ *  * If the return value is not PLDM_SUCCESS, it represents a
+ * transport layer error.
+ *  * If the completion_code value is not PLDM_SUCCESS, it represents a
+ * protocol layer error and all the out-parameters are invalid.
+ *
+ *  @param[in] msg - Response message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[out] completion_code - Pointer to response msg's PLDM completion code
+ *  @param[out] types - pointer to array bitfield8_t[8] containing supported
+ *              types (MAX_TYPES/8) = 8), as per DSP0240
+ *  @return pldm_completion_codes
+ */
+int decode_get_types_resp(const struct pldm_msg *msg, size_t payload_length,
+			  uint8_t *completion_code, bitfield8_t *types);
+
+/* GetPLDMCommands */
+
+/** @brief Create a PLDM request message for GetPLDMCommands
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] type - PLDM Type
+ *  @param[in] version - Version for PLDM Type
+ *  @param[in,out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_get_commands_req(uint8_t instance_id, uint8_t type, ver32_t version,
+			    struct pldm_msg *msg);
+
+/** @brief Decode a GetPLDMCommands response message
+ *
+ *  Note:
+ *  * If the return value is not PLDM_SUCCESS, it represents a
+ * transport layer error.
+ *  * If the completion_code value is not PLDM_SUCCESS, it represents a
+ * protocol layer error and all the out-parameters are invalid.
+ *
+ *  @param[in] msg - Response message
+ *  @param[in] payload_length - Length of reponse message payload
+ *  @param[out] completion_code - Pointer to response msg's PLDM completion code
+ *  @param[in] commands - pointer to array bitfield8_t[32] containing supported
+ *             commands (PLDM_MAX_CMDS_PER_TYPE/8) = 32), as per DSP0240
+ *  @return pldm_completion_codes
+ */
+int decode_get_commands_resp(const struct pldm_msg *msg, size_t payload_length,
+			     uint8_t *completion_code, bitfield8_t *commands);
+
+/* GetPLDMVersion */
+
+/** @brief Create a PLDM request for GetPLDMVersion
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] transfer_handle - Handle to identify PLDM version data transfer.
+ *         This handle is ignored by the responder when the
+ *         transferop_flag is set to getFirstPart.
+ *  @param[in] transfer_opflag - flag to indicate whether it is start of
+ *         transfer
+ *  @param[in] type -  PLDM Type for which version is requested
+ *  @param[in,out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_get_version_req(uint8_t instance_id, uint32_t transfer_handle,
+			   uint8_t transfer_opflag, uint8_t type,
+			   struct pldm_msg *msg);
+
+/** @brief Decode a GetPLDMVersion response message
+ *
+ *  Note:
+ *  * If the return value is not PLDM_SUCCESS, it represents a
+ * transport layer error.
+ *  * If the completion_code value is not PLDM_SUCCESS, it represents a
+ * protocol layer error and all the out-parameters are invalid.
+ *
+ *  @param[in] msg - Response message
+ *  @param[in] payload_length - Length of reponse message payload
+ *  @param[out] completion_code - Pointer to response msg's PLDM completion code
+ *  @param[out] next_transfer_handle - the next handle for the next part of data
+ *  @param[out] transfer_flag - flag to indicate the part of data
+ *  @return pldm_completion_codes
+ */
+int decode_get_version_resp(const struct pldm_msg *msg, size_t payload_length,
+			    uint8_t *completion_code,
+			    uint32_t *next_transfer_handle,
+			    uint8_t *transfer_flag, ver32_t *version);
+
+/* GetTID */
+
+/** @brief Decode a GetTID response message
+ *
+ *  Note:
+ *  * If the return value is not PLDM_SUCCESS, it represents a
+ * transport layer error.
+ *  * If the completion_code value is not PLDM_SUCCESS, it represents a
+ * protocol layer error and all the out-parameters are invalid.
+ *
+ *  @param[in] msg - Response message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[out] completion_code - Pointer to response msg's PLDM completion code
+ *  @param[out] tid - Pointer to the terminus id
+ *  @return pldm_completion_codes
+ */
+int decode_get_tid_resp(const struct pldm_msg *msg, size_t payload_length,
+			uint8_t *completion_code, uint8_t *tid);
+
+/* Responder */
+
+/* GetPLDMTypes */
+
+/** @brief Create a PLDM response message for GetPLDMTypes
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in] types - pointer to array bitfield8_t[8] containing supported
+ *             types (MAX_TYPES/8) = 8), as per DSP0240
+ *  @param[in,out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_get_types_resp(uint8_t instance_id, uint8_t completion_code,
+			  const bitfield8_t *types, struct pldm_msg *msg);
+
+/* GetPLDMCommands */
+
+/** @brief Decode GetPLDMCommands' request data
+ *
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - Length of request message payload
+ *  @param[out] type - PLDM Type
+ *  @param[out] version - Version for PLDM Type
+ *  @return pldm_completion_codes
+ */
+int decode_get_commands_req(const struct pldm_msg *msg, size_t payload_length,
+			    uint8_t *type, ver32_t *version);
+
+/** @brief Create a PLDM response message for GetPLDMCommands
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in] commands - pointer to array bitfield8_t[32] containing supported
+ *             commands (PLDM_MAX_CMDS_PER_TYPE/8) = 32), as per DSP0240
+ *  @param[in,out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_get_commands_resp(uint8_t instance_id, uint8_t completion_code,
+			     const bitfield8_t *commands, struct pldm_msg *msg);
+
+/* GetPLDMVersion */
+
+/** @brief Create a PLDM response for GetPLDMVersion
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in] next_transfer_handle - Handle to identify next portion of
+ *              data transfer
+ *  @param[in] transfer_flag - Represents the part of transfer
+ *  @param[in] version_data - the version data
+ *  @param[in] version_size - size of version data
+ *  @param[in,out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_get_version_resp(uint8_t instance_id, uint8_t completion_code,
+			    uint32_t next_transfer_handle,
+			    uint8_t transfer_flag, const ver32_t *version_data,
+			    size_t version_size, struct pldm_msg *msg);
+
+/** @brief Decode a GetPLDMVersion request message
+ *
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - length of request message payload
+ *  @param[out] transfer_handle - the handle of data
+ *  @param[out] transfer_opflag - Transfer Flag
+ *  @param[out] type - PLDM type for which version is requested
+ *  @return pldm_completion_codes
+ */
+int decode_get_version_req(const struct pldm_msg *msg, size_t payload_length,
+			   uint32_t *transfer_handle, uint8_t *transfer_opflag,
+			   uint8_t *type);
+
+/* Requester */
+
+/* GetTID */
+
+/** @brief Create a PLDM request message for GetTID
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in,out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_get_tid_req(uint8_t instance_id, struct pldm_msg *msg);
+
+/** @brief Create a PLDM response message for GetTID
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in] tid - Terminus ID
+ *  @param[in,out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_get_tid_resp(uint8_t instance_id, uint8_t completion_code,
+			uint8_t tid, struct pldm_msg *msg);
+
+/* Responder */
+
+/* MultipartRecieve */
+
+/** @brief Decode a PLDM MultipartReceive request message
+ *
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - length of request message payload
+ *  @param[out] pldm_type - PLDM type for which version is requested
+ *  @param[out] transfer_opflag - Transfer Flag
+ *  @param[out] transfer_ctx - The context of the packet
+ *  @param[out] transfer_handle - The handle of data
+ *  @param[out] section_offset - The start of the requested section
+ *  @param[out] section_length - The length of the requested section
+ *  @return pldm_completion_codes
+ */
+int decode_multipart_receive_req(
+    const struct pldm_msg *msg, size_t payload_length, uint8_t *pldm_type,
+    uint8_t *transfer_opflag, uint32_t *transfer_ctx, uint32_t *transfer_handle,
+    uint32_t *section_offset, uint32_t *section_length);
+
+/** @brief Create a PLDM response message containing only cc
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] type - PLDM Type
+ *  @param[in] command - PLDM Command
+ *  @param[in] cc - PLDM Completion Code
+ *  @param[out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ */
+int encode_cc_only_resp(uint8_t instance_id, uint8_t type, uint8_t command,
+			uint8_t cc, struct pldm_msg *msg);
+
+/** @brief Create a PLDM message only with the header
+ *
+ *	@param[in] msg_type - PLDM message type
+ *	@param[in] instance_id - Message's instance id
+ *	@param[in] pldm_type - PLDM Type
+ *	@param[in] command - PLDM Command
+ *	@param[out] msg - Message will be written to this
+ *
+ *	@return pldm_completion_codes
+ */
+int encode_pldm_header_only(uint8_t msg_type, uint8_t instance_id,
+			    uint8_t pldm_type, uint8_t command,
+			    struct pldm_msg *msg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BASE_H */
diff --git a/include/libpldm/bios.h b/include/libpldm/bios.h
new file mode 100644
index 0000000..a23a671
--- /dev/null
+++ b/include/libpldm/bios.h
@@ -0,0 +1,618 @@
+#ifndef BIOS_H
+#define BIOS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <asm/byteorder.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base.h"
+#include "utils.h"
+
+/* Response lengths are inclusive of completion code */
+#define PLDM_GET_DATE_TIME_RESP_BYTES 8
+
+#define PLDM_GET_BIOS_TABLE_REQ_BYTES 6
+#define PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES 6
+#define PLDM_SET_BIOS_TABLE_MIN_REQ_BYTES 6
+#define PLDM_SET_BIOS_TABLE_RESP_BYTES 5
+#define PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES 5
+#define PLDM_SET_BIOS_ATTR_CURR_VAL_RESP_BYTES 5
+#define PLDM_GET_BIOS_ATTR_CURR_VAL_BY_HANDLE_REQ_BYTES 7
+#define PLDM_GET_BIOS_ATTR_CURR_VAL_BY_HANDLE_MIN_RESP_BYTES 6
+
+enum pldm_bios_completion_codes {
+	PLDM_BIOS_TABLE_UNAVAILABLE = 0x83,
+	PLDM_INVALID_BIOS_TABLE_DATA_INTEGRITY_CHECK = 0x84,
+	PLDM_INVALID_BIOS_TABLE_TYPE = 0x85,
+	PLDM_INVALID_BIOS_ATTR_HANDLE = 0x88,
+};
+enum pldm_bios_commands {
+	PLDM_GET_BIOS_TABLE = 0x01,
+	PLDM_SET_BIOS_TABLE = 0x02,
+	PLDM_SET_BIOS_ATTRIBUTE_CURRENT_VALUE = 0x07,
+	PLDM_GET_BIOS_ATTRIBUTE_CURRENT_VALUE_BY_HANDLE = 0x08,
+	PLDM_GET_DATE_TIME = 0x0c,
+	PLDM_SET_DATE_TIME = 0x0d,
+};
+
+enum pldm_bios_table_types {
+	PLDM_BIOS_STRING_TABLE,
+	PLDM_BIOS_ATTR_TABLE,
+	PLDM_BIOS_ATTR_VAL_TABLE,
+};
+
+struct pldm_bios_string_table_entry {
+	uint16_t string_handle;
+	uint16_t string_length;
+	char name[1];
+} __attribute__((packed));
+
+struct pldm_bios_attr_table_entry {
+	uint16_t attr_handle;
+	uint8_t attr_type;
+	uint16_t string_handle;
+	uint8_t metadata[1];
+} __attribute__((packed));
+
+struct pldm_bios_enum_attr {
+	uint8_t num_possible_values;
+	uint16_t indices[1];
+} __attribute__((packed));
+
+struct pldm_bios_attr_val_table_entry {
+	uint16_t attr_handle;
+	uint8_t attr_type;
+	uint8_t value[1];
+} __attribute__((packed));
+
+enum pldm_bios_attribute_type {
+	PLDM_BIOS_ENUMERATION = 0x0,
+	PLDM_BIOS_STRING = 0x1,
+	PLDM_BIOS_PASSWORD = 0x2,
+	PLDM_BIOS_INTEGER = 0x3,
+	PLDM_BIOS_ENUMERATION_READ_ONLY = 0x80,
+	PLDM_BIOS_STRING_READ_ONLY = 0x81,
+	PLDM_BIOS_PASSWORD_READ_ONLY = 0x82,
+	PLDM_BIOS_INTEGER_READ_ONLY = 0x83,
+};
+
+/** @struct pldm_get_bios_table_req
+ *
+ *  structure representing GetBIOSTable request packet
+ */
+struct pldm_get_bios_table_req {
+	uint32_t transfer_handle;
+	uint8_t transfer_op_flag;
+	uint8_t table_type;
+} __attribute__((packed));
+
+/** @struct pldm_get_bios_table_resp
+ *
+ *  structure representing GetBIOSTable response packet
+ */
+struct pldm_get_bios_table_resp {
+	uint8_t completion_code;
+	uint32_t next_transfer_handle;
+	uint8_t transfer_flag;
+	uint8_t table_data[1];
+} __attribute__((packed));
+
+/** @struct pldm_get_date_time_resp
+ *
+ *  Structure representing PLDM get date time response
+ */
+struct pldm_get_date_time_resp {
+	uint8_t completion_code; //!< completion code
+	uint8_t seconds;	 //!< Seconds in BCD format
+	uint8_t minutes;	 //!< Minutes in BCD format
+	uint8_t hours;		 //!< Hours in BCD format
+	uint8_t day;		 //!< Day of the month in BCD format
+	uint8_t month;		 //!< Month in BCD format
+	uint16_t year;		 //!< Year in BCD format
+} __attribute__((packed));
+
+/** @struct pldm_set_date_time_req
+ *
+ *  structure representing SetDateTime request packet
+ *
+ */
+struct pldm_set_date_time_req {
+	uint8_t seconds; //!< Seconds in BCD format
+	uint8_t minutes; //!< Minutes in BCD format
+	uint8_t hours;	 //!< Hours in BCD format
+	uint8_t day;	 //!< Day of the month in BCD format
+	uint8_t month;	 //!< Month in BCD format
+	uint16_t year;	 //!< Year in BCD format
+} __attribute__((packed));
+
+/** @struct pldm_only_cc_resp
+ *
+ *  Structure representing PLDM responses only have completion code
+ */
+struct pldm_only_cc_resp {
+	uint8_t completion_code;
+} __attribute__((packed));
+
+/** @struct pldm_get_bios_attribute_current_value_by_handle_req
+ *
+ *  structure representing GetBIOSAttributeCurrentValueByHandle request packet
+ */
+struct pldm_get_bios_attribute_current_value_by_handle_req {
+	uint32_t transfer_handle;
+	uint8_t transfer_op_flag;
+	uint16_t attribute_handle;
+} __attribute__((packed));
+
+/** @struct pldm_get_bios_attribute_current_value_by_handle_resp
+ *
+ *  structure representing GetBIOSAttributeCurrentValueByHandle response
+ */
+struct pldm_get_bios_attribute_current_value_by_handle_resp {
+	uint8_t completion_code;
+	uint32_t next_transfer_handle;
+	uint8_t transfer_flag;
+	uint8_t attribute_data[1];
+} __attribute__((packed));
+
+/** @struct pldm_set_bios_attribute_current_value_req
+ *
+ *  structure representing SetBiosAttributeCurrentValue request packet
+ *
+ */
+struct pldm_set_bios_attribute_current_value_req {
+	uint32_t transfer_handle;
+	uint8_t transfer_flag;
+	uint8_t attribute_data[1];
+} __attribute__((packed));
+
+/** @struct pldm_set_bios_attribute_current_value_resp
+ *
+ *  structure representing SetBiosCurrentValue response packet
+ *
+ */
+struct pldm_set_bios_attribute_current_value_resp {
+	uint8_t completion_code;
+	uint32_t next_transfer_handle;
+} __attribute__((packed));
+
+/** @struct pldm_set_bios_table_req
+ *
+ *  structure representing SetBIOSTable request packet
+ *
+ */
+struct pldm_set_bios_table_req {
+	uint32_t transfer_handle;
+	uint8_t transfer_flag;
+	uint8_t table_type;
+	uint8_t table_data[1];
+} __attribute__((packed));
+
+/** @struct pldm_set_bios_table_resp
+ *
+ *  structure representing SetBIOSTable response packet
+ *
+ */
+struct pldm_set_bios_table_resp {
+	uint8_t completion_code;
+	uint32_t next_transfer_handle;
+} __attribute__((packed));
+
+/* Requester */
+
+/* GetDateTime */
+
+/** @brief Create a PLDM request message for GetDateTime
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.body.payload'
+ */
+
+int encode_get_date_time_req(uint8_t instance_id, struct pldm_msg *msg);
+
+/** @brief Decode a GetDateTime response message
+ *
+ *  Note:
+ *  * If the return value is not PLDM_SUCCESS, it represents a
+ * transport layer error.
+ *  * If the completion_code value is not PLDM_SUCCESS, it represents a
+ * protocol layer error and all the out-parameters are invalid.
+ *
+ *  @param[in] msg - Response message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[out] completion_code - Pointer to response msg's PLDM completion code
+ *  @param[out] seconds - Seconds in BCD format
+ *  @param[out] minutes - minutes in BCD format
+ *  @param[out] hours - hours in BCD format
+ *  @param[out] day - day of month in BCD format
+ *  @param[out] month - number of month in BCD format
+ *  @param[out] year - year in BCD format
+ *  @return pldm_completion_codes
+ */
+int decode_get_date_time_resp(const struct pldm_msg *msg, size_t payload_length,
+			      uint8_t *completion_code, uint8_t *seconds,
+			      uint8_t *minutes, uint8_t *hours, uint8_t *day,
+			      uint8_t *month, uint16_t *year);
+
+/* SetBiosAttributeCurrentValue */
+
+/** @brief Create a PLDM request message for SetBiosAttributeCurrentValue
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] transfer_handle - Handle to identify a BIOS table transfer
+ *  @param[in] transfer_flag - Flag to indicate what part of the transfer
+ * this request represents
+ *  @param[in] attribute_data - Contains current value of attribute
+ *  @param[in] attribute_length - Length of attribute
+ *  @param[out] msg - Message will be written to this
+ *  @param[in] payload_length - Length of message payload
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of params
+ *         'msg.payload'
+ */
+int encode_set_bios_attribute_current_value_req(
+    uint8_t instance_id, uint32_t transfer_handle, uint8_t transfer_flag,
+    const uint8_t *attribute_data, size_t attribute_length,
+    struct pldm_msg *msg, size_t payload_length);
+
+/** @brief Decode a SetBiosAttributeCurrentValue response message
+ *
+ *  Note:
+ *  * If the return value is not PLDM_SUCCESS, it represents a
+ * transport layer error.
+ *  * If the completion_code value is not PLDM_SUCCESS, it represents a
+ * protocol layer error and all the out-parameters are invalid.
+ *
+ *  @param[in] msg - Response message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[out] completion_code - Pointer to response msg's PLDM completion code
+ *  @param[out] next_transfer_handle - Pointer to a handle that identify the
+ *              next portion of the transfer
+ *  @return pldm_completion_codes
+ */
+int decode_set_bios_attribute_current_value_resp(
+    const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
+    uint32_t *next_transfer_handle);
+
+/* SetBIOSTable */
+
+/** @brief Create a PLDM request message for SetBIOSTable
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] transfer_handle - Handle to identify a BIOS table transfer
+ *  @param[in] transfer_flag - Flag to indicate what part of the transfer
+ * 			   this request represents
+ *  @param[in] table_type - Indicates what table is being transferred
+ *             {BIOSStringTable=0x0, BIOSAttributeTable=0x1,
+ *              BIOSAttributeValueTable=0x2}
+ *  @param[in] table_data - Contains data specific to the table type
+ *  @param[in] table_length - Length of table data
+ *  @param[out] msg - Message will be written to this
+ *  @param[in] payload_length - Length of message payload
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of params
+ *         'msg.payload'
+ */
+int encode_set_bios_table_req(uint8_t instance_id, uint32_t transfer_handle,
+			      uint8_t transfer_flag, uint8_t table_type,
+			      const uint8_t *table_data, size_t table_length,
+			      struct pldm_msg *msg, size_t payload_length);
+
+/** @brief Decode a SetBIOSTable response message
+ *
+ *  Note:
+ *  * If the return value is not PLDM_SUCCESS, it represents a
+ * transport layer error.
+ *  * If the completion_code value is not PLDM_SUCCESS, it represents a
+ * protocol layer error and all the out-parameters are invalid.
+ *
+ *  @param[in] msg - Response message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[out] completion_code - Pointer to response msg's PLDM completion code
+ *  @param[out] next_transfer_handle - Pointer to a handle that identify the
+ *              next portion of the transfer
+ *  @return pldm_completion_codes
+ */
+int decode_set_bios_table_resp(const struct pldm_msg *msg,
+			       size_t payload_length, uint8_t *completion_code,
+			       uint32_t *next_transfer_handle);
+
+/* Responder */
+
+/* GetDateTime */
+
+/** @brief Create a PLDM response message for GetDateTime
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in] seconds - seconds in BCD format
+ *  @param[in] minutes - minutes in BCD format
+ *  @param[in] hours - hours in BCD format
+ *  @param[in] day - day of the month in BCD format
+ *  @param[in] month - number of month in BCD format
+ *  @param[in] year - year in BCD format
+ *  @param[out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.body.payload'
+ */
+
+int encode_get_date_time_resp(uint8_t instance_id, uint8_t completion_code,
+			      uint8_t seconds, uint8_t minutes, uint8_t hours,
+			      uint8_t day, uint8_t month, uint16_t year,
+			      struct pldm_msg *msg);
+
+/* GetBIOSTable */
+
+/** @brief Create a PLDM response message for GetBIOSTable
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in] next_transfer_handle - handle to identify the next portion of the
+ * transfer
+ *  @param[in] transfer_flag - To indicate what part of the transfer this
+ * response represents
+ *  @param[in] table_data - BIOS Table type specific data
+ *  @param[in] payload_length - Length of payload message
+ *  @param[out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ */
+int encode_get_bios_table_resp(uint8_t instance_id, uint8_t completion_code,
+			       uint32_t next_transfer_handle,
+			       uint8_t transfer_flag, uint8_t *table_data,
+			       size_t payload_length, struct pldm_msg *msg);
+
+/** @brief Encode  GetBIOSTable request packet
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] transfer_handle - Handle to identify a BIOS table transfer
+ *  @param[in] transfer_op_flag - Flag to indicate the start of a multipart
+ *                                 transfer
+ *  @param[in] table_type - BIOS table type
+ *  @param[out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ */
+int encode_get_bios_table_req(uint8_t instance_id, uint32_t transfer_handle,
+			      uint8_t transfer_op_flag, uint8_t table_type,
+			      struct pldm_msg *msg);
+
+/** @brief Decode GetBIOSTable request packet
+ *
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - Length of request message payload
+ *  @param[out] transfer_handle - Handle to identify a BIOS table transfer
+ *  @param[out] transfer_op_flag - Flag to indicate the start of a multipart
+ * transfer
+ *  @param[out] table_type - BIOS table type
+ *  @return pldm_completion_codes
+ */
+int decode_get_bios_table_req(const struct pldm_msg *msg, size_t payload_length,
+			      uint32_t *transfer_handle,
+			      uint8_t *transfer_op_flag, uint8_t *table_type);
+
+/** @brief Decode GetBIOSTable response packet
+ *
+ *  @param[in] msg - Response message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in] next_transfer_handle - handle to identify the next portion of the
+ *                                    transfer
+ *  @param[in] transfer_flag - To indicate what part of the transfer this
+ *                             response represents
+ *  @param[out] bios_table_offset - Offset where bios table data should be read
+ *                                  in pldm msg
+ *  @return pldm_completion_codes
+ */
+int decode_get_bios_table_resp(const struct pldm_msg *msg,
+			       size_t payload_length, uint8_t *completion_code,
+			       uint32_t *next_transfer_handle,
+			       uint8_t *transfer_flag,
+			       size_t *bios_table_offset);
+
+/* GetBIOSAttributeCurrentValueByHandle */
+
+/** @brief Decode GetBIOSAttributeCurrentValueByHandle request packet
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] transfer_handle - Handle to identify a BIOS attribute transfer
+ *  @param[in] transfer_op_flag - Flag to indicate the start of a multipart
+ *                                 transfer
+ *  @param[in] attribute_handle - Handle to identify the BIOS attribute
+ *  @param[out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ */
+int encode_get_bios_attribute_current_value_by_handle_req(
+    uint8_t instance_id, uint32_t transfer_handle, uint8_t transfer_op_flag,
+    uint16_t attribute_handle, struct pldm_msg *msg);
+
+/** @brief Decode GetBIOSAttributeCurrentValueByHandle response packet
+ *
+ *  @param[in] msg - Response message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[out] completion_code - PLDM completion code
+ *  @param[out] next_transfer_handle - handle to identify the next portion of
+ * the transfer
+ *  @param[out] transfer_flag - To indicate what part of the transfer this
+ *                             response represents
+ *  @param[out] attribute_data - contains current value of attribute
+ *  @return pldm_completion_codes
+ */
+int decode_get_bios_attribute_current_value_by_handle_resp(
+    const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
+    uint32_t *next_transfer_handle, uint8_t *transfer_flag,
+    struct variable_field *attribute_data);
+
+/** @brief Decode GetBIOSAttributeCurrentValueByHandle request packet
+ *
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - Length of request message payload
+ *  @param[out] transfer_handle - Handle to identify a BIOS table transfer
+ *  @param[out] transfer_op_flag - Flag to indicate the start of a multipart
+ * transfer
+ *  @param[out] attribute_handle - Handle to identify the BIOS attribute
+ *  @return pldm_completion_codes
+ */
+int decode_get_bios_attribute_current_value_by_handle_req(
+    const struct pldm_msg *msg, size_t payload_length,
+    uint32_t *transfer_handle, uint8_t *transfer_op_flag,
+    uint16_t *attribute_handle);
+
+/** @brief Create a PLDM response message for
+ * GetBIOSAttributeCurrentValueByHandle
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in] next_transfer_handle - handle to identify the next portion of the
+ * transfer
+ *  @param[in] transfer_flag - To indicate what part of the transfer this
+ * response represents
+ *  @param[in] attribute_data - contains current value of attribute
+ *  @param[in] attribute_length - Length of attribute
+ *  @param[out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ */
+int encode_get_bios_current_value_by_handle_resp(
+    uint8_t instance_id, uint8_t completion_code, uint32_t next_transfer_handle,
+    uint8_t transfer_flag, const uint8_t *attribute_data,
+    size_t attribute_length, struct pldm_msg *msg);
+
+/* SetBiosAttributeCurrentValue */
+
+/** @brief Decode SetBIOSAttributeCurrentValue request packet
+ *
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - Length of request message payload
+ *  @param[out] transfer_handle - Handle to identify a BIOS table transfer
+ *  @param[out] transfer_flag - Flag to indicate what part of the transfer
+ *                              this request represents
+ *  @param[out] attribute - Struct variable_field, contains a pointer to the
+ *                          attribute field in the buffer of \p msg, \p msg must
+ *                          be valid when \p attribute is used.
+ *  @return pldm_completion_codes
+ */
+int decode_set_bios_attribute_current_value_req(
+    const struct pldm_msg *msg, size_t payload_length,
+    uint32_t *transfer_handle, uint8_t *transfer_flag,
+    struct variable_field *attribute);
+
+/** @brief Create a PLDM response message for SetBiosAttributeCurrentValue
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in] next_transfer_handle - handle to identify the next portion of the
+ *  @param[out] msg - Message will be written to this
+ */
+int encode_set_bios_attribute_current_value_resp(uint8_t instance_id,
+						 uint8_t completion_code,
+						 uint32_t next_transfer_handle,
+						 struct pldm_msg *msg);
+
+/** @brief Create a PLDM request message for SetDateTime
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] seconds - Seconds in decimal format. Value range 0~59
+ *  @param[in] minutes - minutes in decimal format. Value range 0~59
+ *  @param[in] hours - hours in decimal format. Value range 0~23
+ *  @param[in] day - day of month in decimal format. Value range 1~31
+ *  @param[in] month - number of month in decimal format. Value range 1~12
+ *  @param[in] year - year in decimal format. Value range 1970~
+ *  @param[out] msg - Message will be written to this
+ *  @param[in] payload_length - Length of request message payload
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.body.payload'
+ */
+int encode_set_date_time_req(uint8_t instance_id, uint8_t seconds,
+			     uint8_t minutes, uint8_t hours, uint8_t day,
+			     uint8_t month, uint16_t year, struct pldm_msg *msg,
+			     size_t payload_length);
+
+/** @brief Decode a SetDateTime request message
+ *
+ *  @param[in] msg - Response message
+ *  @param[in] payload_length - Length of request message payload
+ *  @param[out] seconds - seconds in BCD format
+ *  @param[out] minutes - minutes in BCD format
+ *  @param[out] hours - hours in BCD format
+ *  @param[out] day - day of the month in BCD format
+ *  @param[out] month - number of month in BCD format
+ *  @param[out] year - year in BCD format
+ *  @return pldm_completion_codes
+ */
+int decode_set_date_time_req(const struct pldm_msg *msg, size_t payload_length,
+			     uint8_t *seconds, uint8_t *minutes, uint8_t *hours,
+			     uint8_t *day, uint8_t *month, uint16_t *year);
+
+/** @brief Create a PLDM response message for SetDateTime
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[out] msg - Message will be written to this
+ *  @param[in] payload_length - Length of response message payload
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.body.payload'
+ */
+int encode_set_date_time_resp(uint8_t instance_id, uint8_t completion_code,
+			      struct pldm_msg *msg, size_t payload_length);
+
+/** @brief Decode a SetDateTime response message
+ *
+ *  Note:
+ *  * If the return value is not PLDM_SUCCESS, it represents a
+ * transport layer error.
+ *  * If the completion_code value is not PLDM_SUCCESS, it represents a
+ * protocol layer error and all the out-parameters are invalid.
+ *
+ *  @param[in] msg - Response message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[out] completion_code - Pointer to response msg's PLDM completion code
+ *  @return pldm_completion_codes
+ */
+int decode_set_date_time_resp(const struct pldm_msg *msg, size_t payload_length,
+			      uint8_t *completion_code);
+
+/* SetBIOSTable */
+
+/** @brief Create a PLDM response message for SetBIOSTable
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in] next_transfer_handle - handle to identify the next portion of the
+ *             transfer
+ *  @param[out] msg - Message will be written to this
+ */
+int encode_set_bios_table_resp(uint8_t instance_id, uint8_t completion_code,
+			       uint32_t next_transfer_handle,
+			       struct pldm_msg *msg);
+
+/** @brief Decode SetBIOSTable request packet
+ *
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - Length of request message payload
+ *  @param[out] transfer_handle - Handle to identify a BIOS table transfer
+ *  @param[out] transfer_flag - Flag to indicate what part of the transfer
+ *                              this request represents
+ *  @param[out] table_type - Indicates what table is being transferred
+ *             {BIOSStringTable=0x0, BIOSAttributeTable=0x1,
+ *              BIOSAttributeValueTable=0x2}
+ *  @param[out] table - Struct variable_field, contains data specific to the
+ * 				table type and the length of table data.
+ *  @return pldm_completion_codes
+ */
+int decode_set_bios_table_req(const struct pldm_msg *msg, size_t payload_length,
+			      uint32_t *transfer_handle, uint8_t *transfer_flag,
+			      uint8_t *table_type,
+			      struct variable_field *table);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BIOS_H */
diff --git a/include/libpldm/bios_table.h b/include/libpldm/bios_table.h
new file mode 100644
index 0000000..284efcb
--- /dev/null
+++ b/include/libpldm/bios_table.h
@@ -0,0 +1,728 @@
+#ifndef BIOS_TABLE_H__
+#define BIOS_TABLE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "bios.h"
+#include "utils.h"
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+/** @struct pldm_bios_table_iter
+ *  structure representing bios table iterator
+ */
+struct pldm_bios_table_iter;
+
+/** @brief Create a bios table iterator
+ *  @param[in] table - Pointer to table data
+ *  @param[in] length - Length of table data
+ *  @param[in] type - Type of pldm bios table
+ *  @return Iterator to the beginning
+ */
+struct pldm_bios_table_iter *
+pldm_bios_table_iter_create(const void *table, size_t length,
+			    enum pldm_bios_table_types type);
+
+/** @brief Release a bios table iterator
+ *  @param[in] iter - Pointer to bios table iterator
+ */
+void pldm_bios_table_iter_free(struct pldm_bios_table_iter *iter);
+
+/** @brief Check if the iterator reaches the end of the bios table
+ *  @param[in] iter - Pointer to the bios table iterator
+ *  @return true if iterator reaches the end
+ *  @note *end* is a position after the last entry.
+ */
+bool pldm_bios_table_iter_is_end(const struct pldm_bios_table_iter *iter);
+
+/** @brief Get iterator to next entry
+ *  @param[in] iter - Pointer the bios table iterator
+ */
+void pldm_bios_table_iter_next(struct pldm_bios_table_iter *iter);
+
+/** @brief Get the bios table entry that the iterator points to
+ *  @param[in] iter - Pointer to the bios table iterator
+ *  @return Pointer to an entry in bios table
+ */
+const void *pldm_bios_table_iter_value(struct pldm_bios_table_iter *iter);
+
+/** @brief Get the bios attribute table entry that the iterator points to
+ *  @param[in] iter - Pointer the bios attribute table iterator
+ *  @return Pointer to an entry in bios attribute table
+ */
+static inline const struct pldm_bios_attr_table_entry *
+pldm_bios_table_iter_attr_entry_value(struct pldm_bios_table_iter *iter)
+{
+	return (const struct pldm_bios_attr_table_entry *)
+	    pldm_bios_table_iter_value(iter);
+}
+
+/** @brief Get the bios string table entry that the iterator ponit to
+ *  @param[in] iter - Pointer the bios string table iterator
+ *  @return Pointer to an entry in bios string table
+ */
+static inline const struct pldm_bios_string_table_entry *
+pldm_bios_table_iter_string_entry_value(struct pldm_bios_table_iter *iter)
+{
+	return (const struct pldm_bios_string_table_entry *)
+	    pldm_bios_table_iter_value(iter);
+}
+
+/** @brief Get the bios attribute value table entry that the iterator ponit to
+ *  @param[in] iter - Pointer the bios attribute value table iterator
+ *  @return Pointer to an entry in bios attribute value table
+ */
+static inline const struct pldm_bios_attr_val_table_entry *
+pldm_bios_table_iter_attr_value_entry_value(struct pldm_bios_table_iter *iter)
+{
+	return (const struct pldm_bios_attr_val_table_entry *)
+	    pldm_bios_table_iter_value(iter);
+}
+
+/** @brief Get the length of an entry in the BIOS String Table
+ *  @param[in] string_length - Length of string
+ *  @return Length of an entry in bytes
+ */
+size_t pldm_bios_table_string_entry_encode_length(uint16_t string_length);
+
+/** @brief Create an entry of BIOS String Table
+ *  @param[out] entry - Pointer to a buffer to create an entry
+ *  @param[in] entry_length - Length of the buffer to create an entry
+ *  @param[in] str - String itself
+ *  @param[in] str_length - Length of the string
+ */
+void pldm_bios_table_string_entry_encode(void *entry, size_t entry_length,
+					 const char *str, uint16_t str_length);
+
+/** @brief Create an entry of BIOS String Table and check the validity of the
+ * parameters
+ *  @param[out] entry - Pointer to a buffer to create an entry
+ *  @param[in] entry_length - Length of the buffer to create an entry
+ *  @param[in] str - String itself
+ *  @param[in] str_length - Length of the string
+ *  @return pldm_completion_codes
+ */
+int pldm_bios_table_string_entry_encode_check(void *entry, size_t entry_length,
+					      const char *str,
+					      uint16_t str_length);
+
+/** @brief Get the string handle for the entry
+ *  @param[in] entry - Pointer to a bios string table entry
+ *  @return Handle to identify a string in the bios string table
+ */
+uint16_t pldm_bios_table_string_entry_decode_handle(
+    const struct pldm_bios_string_table_entry *entry);
+
+/** @brief Get the string length for the entry
+ *  @param[in] entry - Pointer to a bios string table entry
+ *  @return Length of string in bytes
+ */
+uint16_t pldm_bios_table_string_entry_decode_string_length(
+    const struct pldm_bios_string_table_entry *entry);
+
+/** @brief Get the string(at most one less than *size* characters) from the
+ * entry
+ *  @param[in] entry - Pointer to a bios string table entry
+ *  @param[out] buffer - Pointer to a buffer to store the string
+ *  @param[in] size - Size of the buffer to store the string
+ *  @return Length of the string decoded
+ */
+uint16_t pldm_bios_table_string_entry_decode_string(
+    const struct pldm_bios_string_table_entry *entry, char *buffer,
+    size_t size);
+
+/** @brief Get the string from the entry and check the validity of the
+ * parameters
+ *  @param[in] entry - Pointer to a bios string table entry
+ *  @param[out] buffer - Pointer to a buffer to store the string
+ *  @param[in] size - Size of the buffer to store the string
+ *  @return pldm_completion_codes
+ */
+int pldm_bios_table_string_entry_decode_string_check(
+    const struct pldm_bios_string_table_entry *entry, char *buffer,
+    size_t size);
+
+/** @brief Find an entry in bios string table by string
+ *  @param[in] table - The BIOS String Table
+ *  @param[in] length - Length of the BIOS String Table
+ *  @param[in] str - String itself
+ *  @return Pointer to an entry in the bios string table
+ */
+const struct pldm_bios_string_table_entry *
+pldm_bios_table_string_find_by_string(const void *table, size_t length,
+				      const char *str);
+/** @brief Find an entry in bios string table by handle
+ *  @param[in] table - The BIOS String Table
+ *  @param[in] length - Length of the BIOS String Table
+ *  @param[in] handle - Handle to identify a string in the bios string table
+ *  @return Pointer to an entry in the bios string table
+ */
+const struct pldm_bios_string_table_entry *
+pldm_bios_table_string_find_by_handle(const void *table, size_t length,
+				      uint16_t handle);
+
+/** @brief Get the attribute handle from the attribute table entry
+ *  @param[in] entry - Pointer to bios attribute table entry
+ *  @return handle to identify the attribute in the attribute table
+ */
+uint16_t pldm_bios_table_attr_entry_decode_attribute_handle(
+    const struct pldm_bios_attr_table_entry *entry);
+
+/** @brief Get the attribute type of the attribute table entry
+ *  @param[in] entry - Pointer to bios attribute table entry
+ *  @return Type of the attribute table entry
+ */
+uint8_t pldm_bios_table_attr_entry_decode_attribute_type(
+    const struct pldm_bios_attr_table_entry *entry);
+
+/** @brief Get the attribute name handle from the attribute table entry
+ *  @param[in] entry - Pointer to bios attribute table entry
+ *  @return handle to identify the name of the attribute, this handle points
+ *          to a string in the bios string table.
+ */
+uint16_t pldm_bios_table_attr_entry_decode_string_handle(
+    const struct pldm_bios_attr_table_entry *entry);
+
+/** @brief Find an entry in attribute table by handle
+ *  @param[in] table - The BIOS Attribute Table
+ *  @param[in] length - Length of the BIOS Attribute Table
+ *  @param[in] handle - handle to identify the attribute in the attribute table
+ *  @return Pointer to the entry
+ */
+const struct pldm_bios_attr_table_entry *
+pldm_bios_table_attr_find_by_handle(const void *table, size_t length,
+				    uint16_t handle);
+
+/** @brief Find an entry in attribute table by string handle
+ *  @param[in] table - The BIOS Attribute Table
+ *  @param[in] length - Length of the BIOS Attribute Table
+ *  @param[in] handle - The string handle
+ *  @return Pointer to the entry
+ */
+const struct pldm_bios_attr_table_entry *
+pldm_bios_table_attr_find_by_string_handle(const void *table, size_t length,
+					   uint16_t handle);
+
+/** @struct pldm_bios_table_attr_entry_enum_info
+ *
+ *  An auxiliary structure for passing parameters to @ref
+ * pldm_bios_table_attr_entry_enum_encode
+ *
+ */
+struct pldm_bios_table_attr_entry_enum_info {
+	uint16_t name_handle; //!< attribute name handle
+	bool read_only;	      //!< indicate whether the attribute is read-only
+	uint8_t pv_num;	      //!< number of possible values
+	const uint16_t *pv_handle; //!< handles of possible values
+	uint8_t def_num;	   //!< nnumber of default values
+	const uint8_t *def_index;  //!< indices of default values.
+};
+
+/** @brief Get length that an attribute entry(type: enum) will take
+ *  @param[in] pv_num - Number of possible values
+ *  @param[in] def_num - Number of default values
+ *  @return The length that an entry(type: enum) will take
+ */
+size_t pldm_bios_table_attr_entry_enum_encode_length(uint8_t pv_num,
+						     uint8_t def_num);
+
+/** @brief Create an entry of BIOS Attribute Table (type: enum)
+ *  @param[out] entry - Pointer to a buffer to create an entry
+ *  @param[in] entry_length - Length of the buffer to create an entry
+ *  @param[in] info - Pointer to an auxiliary structure @ref
+ * pldm_bios_table_attr_entry_enum_info
+ */
+void pldm_bios_table_attr_entry_enum_encode(
+    void *entry, size_t entry_length,
+    const struct pldm_bios_table_attr_entry_enum_info *info);
+
+/** @brief Create an entry of BIOS Attribute Table (type: enum) and check the
+ * validity of the parameters
+ *  @param[out] entry - Pointer to a buffer to create an entry
+ *  @param[in] entry_length - Length of the buffer to create an entry
+ *  @param[in] info - Pointer to an auxiliary structure @ref
+ * pldm_bios_table_attr_entry_enum_info
+ *  @return pldm_completion_codes
+ */
+int pldm_bios_table_attr_entry_enum_encode_check(
+    void *entry, size_t entry_length,
+    const struct pldm_bios_table_attr_entry_enum_info *info);
+
+/** @brief Get the total number of possible values for the entry
+ *  @param[in] entry - Pointer to bios attribute table entry
+ *  @return total number of possible values
+ */
+uint8_t pldm_bios_table_attr_entry_enum_decode_pv_num(
+    const struct pldm_bios_attr_table_entry *entry);
+
+/** @brief Get the total number of possible values for the entry and check the
+ * validity of the parameters
+ *  @param[in] entry - Pointer to bios attribute table entry
+ *  @param[out] pv_num - Pointer to total number of possible values
+ *  @return pldm_completion_codes
+ */
+int pldm_bios_table_attr_entry_enum_decode_pv_num_check(
+    const struct pldm_bios_attr_table_entry *entry, uint8_t *pv_num);
+
+/** @brief Get the total number of default values for the entry
+ *  @param[in] entry - Pointer to bios attribute table entry
+ *  @return total number of default values
+ */
+uint8_t pldm_bios_table_attr_entry_enum_decode_def_num(
+    const struct pldm_bios_attr_table_entry *entry);
+
+/** @brief Get the total number of default values for the entry and check the
+ * validity of the parameters
+ *  @param[in] entry - Pointer to bios attribute table entry
+ *  @param[out] def_num - Pointer to total number of default values
+ *  @return pldm_completion_codes
+ */
+int pldm_bios_table_attr_entry_enum_decode_def_num_check(
+    const struct pldm_bios_attr_table_entry *entry, uint8_t *def_num);
+
+/** @brief Get possible values string handles
+ *  @param[in] entry - Pointer to bios attribute table entry
+ *  @param[out] pv_hdls - Pointer to a buffer to stroe
+ * PossibleValuesStringHandles
+ *  @param[in] pv_num - Number of PossibleValuesStringHandles expected
+ *  @return pldm_completion_codes
+ */
+uint8_t pldm_bios_table_attr_entry_enum_decode_pv_hdls(
+    const struct pldm_bios_attr_table_entry *entry, uint16_t *pv_hdls,
+    uint8_t pv_num);
+
+/** @brief Get possible values string handles and check the validity of the
+ * parameters
+ *  @param[in] entry - Pointer to bios attribute table entry
+ *  @param[out] pv_hdls - Pointer to a buffer to stroe
+ * PossibleValuesStringHandles
+ *  @param[in] pv_num - Number of PossibleValuesStringHandles the buffer can
+ * stroe
+ *  @return Number of PossibleValuesStringHandles decoded
+ */
+int pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
+    const struct pldm_bios_attr_table_entry *entry, uint16_t *pv_hdls,
+    uint8_t pv_num);
+
+/** @brief Get Indices of default values
+ *  @param[in] entry - Pointer to bios attribute table entry
+ *  @param[out] def_indices - Pointer to a buffer to store
+ *                            default value indices
+ *  @param[in] def_num - Number of DefaultValues the buffer can
+ *                       store
+ *  @return Number of default values decoded
+ */
+uint8_t pldm_bios_table_attr_entry_enum_decode_def_indices(
+    const struct pldm_bios_attr_table_entry *entry, uint8_t *def_indices,
+    uint8_t def_num);
+
+/** @struct pldm_bios_table_attr_entry_string_info
+ *
+ *  An auxiliary structure for passing parameters to @ref
+ * pldm_bios_table_attr_entry_string_encode
+ *
+ */
+struct pldm_bios_table_attr_entry_string_info {
+	uint16_t name_handle;	//!< attribute name handle
+	bool read_only;		//!< indicate whether the attribute is read-only
+	uint8_t string_type;	//!< The type of the string
+	uint16_t min_length;	//!< The minimum length of the string in bytes
+	uint16_t max_length;	//!< The maximum length of the string in bytes
+	uint16_t def_length;	//!< The length of the defaut string in bytes
+	const char *def_string; //!< The default string itself
+};
+
+/** @brief Check fields in @ref pldm_bios_table_attr_entry_string_info
+ *  @param[in] info - Pointer to the pldm_bios_table_attr_entry_string_info
+ *  @param[out] errmsg - Pointer to an errmsg stored in the statically allocated
+ * memory
+ *  @return pldm_completion_codes
+ */
+int pldm_bios_table_attr_entry_string_info_check(
+    const struct pldm_bios_table_attr_entry_string_info *info,
+    const char **errmsg);
+
+/** @brief Get length that an attribute entry(type: string) will take
+ *  @param[in] def_str_len - Length of default string
+ *  @return The length that an entry(type: string) will take
+ */
+size_t pldm_bios_table_attr_entry_string_encode_length(uint16_t def_str_len);
+
+/** @brief Create an entry of BIOS Attribute Table (type: string)
+ *  @param[out] entry - Pointer to a buffer to create an entry
+ *  @param[in] entry_length - Length of the buffer to create an entry
+ *  @param[in] info - Pointer to an auxiliary structure @ref
+ * pldm_bios_table_attr_entry_string_info
+ */
+void pldm_bios_table_attr_entry_string_encode(
+    void *entry, size_t entry_length,
+    const struct pldm_bios_table_attr_entry_string_info *info);
+
+/** @brief Create an entry of BIOS Attribute Table (type: string) and check the
+ * validity of the parameters
+ *  @param[out] entry - Pointer to a buffer to create an entry
+ *  @param[in] entry_length - Length of the buffer to create an entry
+ *  @param[in] info - Pointer to an auxiliary structure @ref
+ * pldm_bios_table_attr_entry_string_info
+ *  @return pldm_completion_codes
+ */
+int pldm_bios_table_attr_entry_string_encode_check(
+    void *entry, size_t entry_length,
+    const struct pldm_bios_table_attr_entry_string_info *info);
+
+/** @brief Get the length of default string in bytes for the entry
+ *  @param[in] entry - Pointer to bios attribute table entry
+ *  @return length of default string in bytes
+ */
+uint16_t pldm_bios_table_attr_entry_string_decode_def_string_length(
+    const struct pldm_bios_attr_table_entry *entry);
+
+/** @brief Get the length of default string in bytes for the entry and check the
+ * validity of the parameters
+ *  @param[in] entry - Pointer to bios attribute table entry
+ *  @param[out] def_string_length Pointer to length of default string in bytes
+ *  @return pldm_completion_codes
+ */
+int pldm_bios_table_attr_entry_string_decode_def_string_length_check(
+    const struct pldm_bios_attr_table_entry *entry,
+    uint16_t *def_string_length);
+
+/** @brief Get the type of string of bios attribute table entry
+ *  @param[in] entry - Pointer to bios attribute table entry
+ *  @return Type of the string
+ */
+uint8_t pldm_bios_table_attr_entry_string_decode_string_type(
+    const struct pldm_bios_attr_table_entry *entry);
+
+/** @brief Get maximum length of the string from a bios attribute table entry in
+ * bytes
+ *  @param[in] entry - Pointer to a bios attribute table entry
+ *  @return Maximum length of the string
+ */
+uint16_t pldm_bios_table_attr_entry_string_decode_max_length(
+    const struct pldm_bios_attr_table_entry *entry);
+
+/** @brief Get minimum length of the string from a bios attribute table entry in
+ * bytes
+ *  @param[in] entry - Pointer to a bios attribute table entry
+ *  @return Minimum length of the string
+ */
+uint16_t pldm_bios_table_attr_entry_string_decode_min_length(
+    const struct pldm_bios_attr_table_entry *entry);
+
+/** @brief Get the default string from a bios attribute table entry
+ *  @param[out] buffer - Pointer to a buffer to store the string
+ *  @param[in] size - Size of the buffer to store the string
+ *  @return Length of the string decoded
+ */
+uint16_t pldm_bios_table_attr_entry_string_decode_def_string(
+    const struct pldm_bios_attr_table_entry *entry, char *buffer, size_t size);
+
+/** @struct pldm_bios_table_attr_entry_integer_info
+ *
+ *  An auxiliary structure for passing parameters to @ref
+ * pldm_bios_table_attr_entry_integer_encode
+ *
+ */
+struct pldm_bios_table_attr_entry_integer_info {
+	uint16_t name_handle; //!< attribute name handle
+	bool read_only;	      //!< indicate whether the attribute is read-only
+	uint64_t lower_bound; //!< The lower bound on the integer value
+	uint64_t upper_bound; //!< The upper bound on the integer value
+	uint32_t scalar_increment; //!< The scalar value that is used for the
+				   //!< increments to this integer
+	uint64_t default_value;	   //!< The default value of the integer
+};
+
+/** @brief Check fields in @ref pldm_bios_table_attr_entry_integer_info
+ *  @param[in] info - Pointer to the pldm_bios_table_attr_entry_integer_info
+ *  @param[out] errmsg - Pointer to an errmsg stored in the statically allocated
+ * memory
+ *  @return pldm_completion_codes
+ */
+int pldm_bios_table_attr_entry_integer_info_check(
+    const struct pldm_bios_table_attr_entry_integer_info *info,
+    const char **errmsg);
+
+/** @brief Get length that an attribute entry(type: integer) will take
+ *  @return The length that an entry(type: integer) will take
+ */
+size_t pldm_bios_table_attr_entry_integer_encode_length();
+
+/** @brief Create an entry of BIOS Attribute Table (type: integer)
+ *  @param[out] entry - Pointer to a buffer to create an entry
+ *  @param[in] entry_length - Length of the buffer to create an entry
+ *  @param[in] info - Pointer to an auxiliary structure @ref
+ * pldm_bios_table_attr_entry_integer_info
+ */
+void pldm_bios_table_attr_entry_integer_encode(
+    void *entry, size_t entry_length,
+    const struct pldm_bios_table_attr_entry_integer_info *info);
+
+/** @brief Create an entry of BIOS Attribute Table (type: integer) and check the
+ * validity of the parameters
+ *  @param[out] entry - Pointer to a buffer to create an entry
+ *  @param[in] entry_length - Length of the buffer to create an entry
+ *  @param[in] info - Pointer to an auxiliary structure @ref
+ * pldm_bios_table_attr_entry_integer_info
+ *  @return pldm_completion_codes
+ */
+int pldm_bios_table_attr_entry_integer_encode_check(
+    void *entry, size_t entry_length,
+    const struct pldm_bios_table_attr_entry_integer_info *info);
+
+/** @brief Decode the specific fields(integer) of attribute table entry
+ *  @param[in] entry - Pointer to an entry of attribute table
+ *  @param[out] lower - The lower bound on the integer value
+ *  @param[out] upper - The upper bound on the integer value
+ *  @param[out] scalar - The scalar value that is used for the increments to
+ *                       this integer
+ *  @param[out] def - The default value of the integer
+ */
+void pldm_bios_table_attr_entry_integer_decode(
+    const struct pldm_bios_attr_table_entry *entry, uint64_t *lower,
+    uint64_t *upper, uint32_t *scalar, uint64_t *def);
+
+/** @brief Get the attribute handle from the attribute value table entry
+ *  @param[in] entry - Pointer to bios attribute value table entry
+ *  @return handle to identify the attribute in the attribute value table
+ */
+uint16_t pldm_bios_table_attr_value_entry_decode_attribute_handle(
+    const struct pldm_bios_attr_val_table_entry *entry);
+
+/** @brief Get the attribute type from the attribute value table entry
+ *  @param[in] entry - Pointer to bios attribute value table entry
+ *  @return Type of the attribute value entry
+ */
+uint8_t pldm_bios_table_attr_value_entry_decode_attribute_type(
+    const struct pldm_bios_attr_val_table_entry *entry);
+
+/** @brief Get length that an attribute value entry(type: enum) will take
+ *  @param[in] count - Total number of current values for this enumeration
+ *  @return The length that an entry(type: enum) will take
+ */
+size_t pldm_bios_table_attr_value_entry_encode_enum_length(uint8_t count);
+
+/** @brief Create an attribute value entry(type: enum)
+ *  @param[out] entry - Pointer to bios attribute value entry
+ *  @param[in] entry_length - Length of attribute value entry
+ *  @param[in] attr_handle - This handle points to an attribute in the
+ *  BIOS Attribute Vlaue Table.
+ *  @param[in] attr_type - Type of this attribute in the BIOS Attribute Value
+ * Table
+ *  @param[in] count - Total number of current values for this enum attribute
+ *  @param[in] handle_indexes - Index into the array(provided in the BIOS
+ * Attribute Table) of the possible values of string handles for this attribute.
+ */
+void pldm_bios_table_attr_value_entry_encode_enum(
+    void *entry, size_t entry_length, uint16_t attr_handle, uint8_t attr_type,
+    uint8_t count, const uint8_t *handle_indexes);
+
+/** @brief Get number of current values for the enum entry
+ *  @param[in] entry - Pointer to bios attribute value table entry
+ *  @return Total number of current values for this enumeration
+ */
+uint8_t pldm_bios_table_attr_value_entry_enum_decode_number(
+    const struct pldm_bios_attr_val_table_entry *entry);
+
+/** @brief Get CurrentValueStringHandleIndex
+ *  @param[in] entry - Pointer to bios attribute value table entry
+ *  @param[in, out] handles - Pointer to a buffer to store
+ *                            CurrentValueStringHandleIndex
+ *  @param[in] number - Number of PossibleValuesStringHandles expected
+ *  @return Number of CurrentValueStringHandleIndex decoded.
+ */
+uint8_t pldm_bios_table_attr_value_entry_enum_decode_handles(
+    const struct pldm_bios_attr_val_table_entry *entry, uint8_t *handles,
+    uint8_t number);
+
+/** @brief Create an attribute value entry(type: enum) and check the validity of
+ * the parameters
+ *  @param[out] entry - Pointer to bios attribute value entry
+ *  @param[in] entry_length - Length of attribute value entry
+ *  @param[in] attr_handle - This handle points to an attribute in the
+ *  BIOS Attribute Vlaue Table.
+ *  @param[in] attr_type - Type of this attribute in the BIOS Attribute Value
+ * Table
+ *  @param[in] count - Total number of current values for this enum attribute
+ *  @param[in] handle_indexes - Index into the array(provided in the BIOS
+ * Attribute Table) of the possible values of string handles for this attribute.
+ *  @return pldm_completion_codes
+ */
+int pldm_bios_table_attr_value_entry_encode_enum_check(
+    void *entry, size_t entry_length, uint16_t attr_handle, uint8_t attr_type,
+    uint8_t count, uint8_t *handle_indexes);
+
+/** @brief Get length that an attribute value entry(type: string) will take
+ *  @param[in] string_length - Length of the current string in byte, 0 indicates
+ *  that the current string value is not set.
+ *  @return The length that an entry(type: string) will take
+ */
+size_t
+pldm_bios_table_attr_value_entry_encode_string_length(uint16_t string_length);
+
+/** @brief Create an attribute value entry(type: string)
+ *  @param[out] entry - Pointer to bios attribute value entry
+ *  @param[in] entry_length - Length of attribute value entry
+ *  @param[in] attr_handle - This handle points to an attribute in the
+ *  BIOS Attribute Vlaue Table.
+ *  @param[in] attr_type - Type of this attribute in the BIOS Attribute Value
+ * Table
+ *  @param[in] string_length - Length of current string in bytes. 0 indicates
+ * that the current string value is not set.
+ *  @param[in] string - The current string itsel
+ */
+void pldm_bios_table_attr_value_entry_encode_string(
+    void *entry, size_t entry_length, uint16_t attr_handle, uint8_t attr_type,
+    uint16_t string_length, const char *string);
+
+/** @brief Get length of the current string in bytes
+ *  @param [in] entry - Pointer to bios attribute value table entry
+ *  @return The length of the current string in bytes
+ */
+uint16_t pldm_bios_table_attr_value_entry_string_decode_length(
+    const struct pldm_bios_attr_val_table_entry *entry);
+
+/** @brief Get Current String Itself
+ *  @param[in] entry - Pointer to bios attribute value table entry
+ *  @param[in, out] current_string - Struct variable_field, contains a pointer
+ *                                   to the CurrentString field in the buffer of
+ *                                    \p entry, \p entry must be valid
+ *                                    when \p current_string is used.
+ */
+void pldm_bios_table_attr_value_entry_string_decode_string(
+    const struct pldm_bios_attr_val_table_entry *entry,
+    struct variable_field *current_string);
+
+/** @brief Create an attribute value entry(type: string) and check the validity
+ * of the parameters
+ *  @param[out] entry - Pointer to bios attribute value entry
+ *  @param[in] entry_length - Length of attribute value entry
+ *  @param[in] attr_handle - This handle points to an attribute in the
+ *  BIOS Attribute Vlaue Table.
+ *  @param[in] attr_type - Type of this attribute in the BIOS Attribute Value
+ * Table
+ *  @param[in] string_length - Length of current string in bytes. 0 indicates
+ * that the current string value is not set.
+ *  @param[in] string - The current string itsel
+ *  @return pldm_completion_codes
+ */
+int pldm_bios_table_attr_value_entry_encode_string_check(
+    void *entry, size_t entry_length, uint16_t attr_handle, uint8_t attr_type,
+    uint16_t string_length, const char *string);
+
+/** @brief Get length that an attribute value entry(type: integer) will take
+ *  @return The length that an entry(type: integer) will take
+ */
+size_t pldm_bios_table_attr_value_entry_encode_integer_length();
+
+/** @brief Create an attribute value entry(type: integer)
+ *  @param[out] entry - Pointer to bios attribute value entry
+ *  @param[in] entry_length - Length of attribute value entry
+ *  @param[in] attr_handle - This handle points to an attribute in the
+ *  BIOS Attribute Vlaue Table.
+ *  @param[in] attr_type - Type of this attribute in the BIOS Attribute Value
+ * Table
+ *  @param[in] cv - Current Value
+ */
+void pldm_bios_table_attr_value_entry_encode_integer(void *entry,
+						     size_t entry_length,
+						     uint16_t attr_handle,
+						     uint8_t attr_type,
+						     uint64_t cv);
+
+/** @brief Get current values for the integer entry
+ *  @param[in] entry - Pointer to bios attribute value table entry
+ *  @return Current Value
+ */
+uint64_t pldm_bios_table_attr_value_entry_integer_decode_cv(
+    const struct pldm_bios_attr_val_table_entry *entry);
+
+/** @brief Create an attribute value entry(type: integer) and check the validity
+ * of the parameters
+ *  @param[out] entry - Pointer to bios attribute value entry
+ *  @param[in] entry_length - Length of attribute value entry
+ *  @param[in] attr_handle - This handle points to an attribute in the
+ *  BIOS Attribute Vlaue Table.
+ *  @param[in] attr_type - Type of this attribute in the BIOS Attribute Value
+ * Table
+ *  @param[in] cv - Current Value
+ *  @return pldm_completion_codes
+ */
+int pldm_bios_table_attr_value_entry_encode_integer_check(void *entry,
+							  size_t entry_length,
+							  uint16_t attr_handle,
+							  uint8_t attr_type,
+							  uint64_t cv);
+
+/** @brief Get the handle from the attribute value entry
+ *  @param[in] entry - Pointer to bios attribute value entry
+ *  @return handle to identify the attribute in the attribute value table
+ */
+uint16_t pldm_bios_table_attr_value_entry_decode_handle(
+    const struct pldm_bios_attr_val_table_entry *entry);
+
+/** @brief Get the length of the attribute value entry
+ *  @param[in] entry - Pointer to bios attribute value entry
+ *  @return Length of the entry
+ */
+size_t pldm_bios_table_attr_value_entry_length(
+    const struct pldm_bios_attr_val_table_entry *entry);
+
+/** @brief Find an entry in attribute value table by handle
+ *  @param[in] table - The BIOS Attribute Value Table
+ *  @param[in] length - Length of the BIOS Attribute Value Table
+ *  @param[in] handle - handle to identify the attribute in the attribute value
+ * table
+ *  @return Pointer to the entry
+ */
+const struct pldm_bios_attr_val_table_entry *
+pldm_bios_table_attr_value_find_by_handle(const void *table, size_t length,
+					  uint16_t handle);
+
+/** @brief Get the size of pad and checksum
+ *  @param[in] size_without_pad - Table size without pad
+ *  @return The size of pad and checksum
+ */
+size_t pldm_bios_table_pad_checksum_size(size_t size_without_pad);
+
+/** @brief Append pad and checksum at the end of the table
+ *  @param[in,out] table - Pointer to a buffer of a bios table
+ *  @param[in] size - Size of the buffer of a bios table
+ *  @param[in] size_without_pad - Table size without pad and checksum
+ *  @return Total size of the table
+ */
+size_t pldm_bios_table_append_pad_checksum(void *table, size_t size,
+					   size_t size_without_pad);
+
+/** @brief Build a new table and update an entry
+ *  @param[in] src_table - Pointer to the source table
+ *  @param[in] src_length - Size of the source table
+ *  @param[out] dest_table - Pointer to the buffer of destination table
+ *  @param[in,out] dest_length - Buffer size of the destination table as input
+ *                               parameter and will be assigned the length of
+ *                               the new table, if the function returns
+ * 				 PLDM_SUCCESS
+ *  @param[in] entry - Pointer to an entry
+ *  @param[in] entry_length - Size of the entry
+ *  @return pldm_completion_codes
+ */
+int pldm_bios_table_attr_value_copy_and_update(
+    const void *src_table, size_t src_length, void *dest_table,
+    size_t *dest_length, const void *entry, size_t entry_length);
+
+/** @brief Verify the crc value of the complete table
+ *  @param[in] table - Pointer to a buffer of a bios table
+ *  @param[in] size - Size of the buffer of a bios table
+ *  @return true: crc value is correct
+ */
+bool pldm_bios_table_checksum(const uint8_t *table, size_t size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/libpldm/entity.h b/include/libpldm/entity.h
new file mode 100644
index 0000000..9e657c1
--- /dev/null
+++ b/include/libpldm/entity.h
@@ -0,0 +1,149 @@
+#ifndef ENTITY_H
+#define ENTITY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief PLDM Entity ID Codes in DSP0249_1.1.0 specification
+ */
+enum pldm_entity_id_codes {
+	PLDM_ENTITY_UNSPECIFIED = 0,
+	PLDM_ENTITY_OTHER = 1,
+
+	/* Miscellaneous Entities */
+	PLDM_ENTITY_NETWORK = 2,
+	PLDM_ENTITY_GROUP = 3,
+	PLDM_ENTITY_REMOTE_MGMT_COMM_DEVICE = 4,
+	PLDM_ENTITY_EXTERNAL_ENVIRONMENT = 5,
+	PLDM_ENTITY_COMM_CHANNEL = 6,
+	PLDM_ENTITY_TERMINUS = 7,
+	PLDM_ENTITY_PLATFORM_EVENT_LOG = 8,
+
+	/* Human Interface Entities */
+	PLDM_ENTITY_KEYPAD = 15,
+	PLDM_ENTITY_SWITCH = 16,
+	PLDM_ENTITY_PUSHBUTTON = 17,
+	PLDM_ENTITY_DISPLAY = 18,
+	PLDM_ENTITY_INDICATOR = 19,
+
+	/* Software/Firmware Entities */
+	PLDM_ENTITY_SYS_MGMT_SW = 30,
+	PLDM_ENTITY_SYS_FIRMWARE = 31,
+	PLDM_ENTITY_OPERATING_SYS = 32,
+	PLDM_ENTITY_VIRTUAL_MACHINE_MANAGER = 33,
+	PLDM_ENTITY_OS_LOADER = 34,
+	PLDM_ENTITY_DEVICE_DRIVER = 35,
+	PLDM_ENTITY_MGMT_CONTROLLER_FW = 36,
+
+	/* Chassis/Enclosure Entities */
+	PLDM_ENTITY_SYSTEM_CHASSIS = 45,
+	PLDM_ENTITY_SUB_CHASSIS = 46,
+	PLDM_ENTITY_DISK_DRIVE_BAY = 47,
+	PLDM_ENTITY_PERIPHERAL_BAY = 48,
+	PLDM_ENTITY_DEVICE_BAY = 49,
+	PLDM_ENTITY_DOOR = 50,
+	PLDM_ENTITY_ACCESS_PANEL = 51,
+	PLDM_ENTITY_COVER = 52,
+
+	/* Board/Card/Module Entities */
+	PLDM_ENTITY_BOARD = 60,
+	PLDM_ENTITY_CARD = 61,
+	PLDM_ENTITY_MODULE = 62,
+	PLDM_ENTITY_SYS_MGMT_MODULE = 63,
+	PLDM_ENTITY_SYS_BOARD = 64,
+	PLDM_ENTITY_MEMORY_BOARD = 65,
+	PLDM_ENTITY_MEMORY_MODULE = 66,
+	PLDM_ENTITY_PROC_MODULE = 67,
+	PLDM_ENTITY_ADD_IN_CARD = 68,
+	PLDM_ENTITY_CHASSIS_FRONT_PANEL_BOARD = 69,
+	PLDM_ENTITY_BACK_PANEL_BOARD = 70,
+	PLDM_ENTITY_POWER_MGMT = 71,
+	PLDM_ENTITY_POWER_SYS_BOARD = 72,
+	PLDM_ENTITY_DRIVE_BACKPLANE = 73,
+	PLDM_ENTITY_SYS_INTERNAL_EXPANSION_BOARD = 74,
+	PLDM_ENTITY_OTHER_SYS_BOARD = 75,
+	PLDM_ENTITY_CHASSIS_BACK_PANEL_BOARD = 76,
+	PLDM_ENTITY_PROCESSING_BLADE = 77,
+	PLDM_ENTITY_CONNECTIVITY_SWITCH = 78,
+	PLDM_ENTITY_PROC_MEMORY_MODULE = 79,
+	PLDM_ENTITY_IO_MODULE = 80,
+	PLDM_ENTITY_PROC_IO_MODULE = 81,
+
+	/* Cooling Entities */
+	PLDM_ENTITY_COOLING_DEVICE = 90,
+	PLDM_ENTITY_COOLING_SUBSYSTEM = 91,
+	PLDM_ENTITY_COOLING_UNIT = 92,
+	PLDM_ENTITY_FAN = 93,
+	PLDM_ENTITY_PELTIER_COOLING_DEVICE = 94,
+	PLDM_ENTITY_LIQUID_COOLING_DEVICE = 95,
+	PLDM_ENTITY_LIQUID_COOLING_SUBSYSTEM = 96,
+
+	/* Storage Device Entities */
+	PLDM_ENTITY_OTHER_STORAGE_DEVICE = 105,
+	PLDM_ENTITY_FLOPPY_DRIVE = 106,
+	PLDM_ENTITY_FIXED_DISK_HARD_DRIVE = 107,
+	PLDM_ENTITY_CD_DRIVE = 108,
+	PLDM_ENTITY_CD_DVD_DRIVE = 109,
+	PLDM_ENTITY_OTHER_SILICON_STORAGE_DEVICE = 110,
+	PLDM_ENTITY_SOLID_STATE_SRIVE = 111,
+
+	/* Power Entities */
+	PLDM_ENTITY_POWER_SUPPLY = 120,
+	PLDM_ENTITY_BATTERY = 121,
+	PLDM_ENTITY_SUPER_CAPACITOR = 122,
+	PLDM_ENTITY_POWER_CONVERTER = 123,
+	PLDM_ENTITY_DC_DC_CONVERTER = 124,
+	PLDM_ENTITY_AC_MAINS_POWER_SUPPLY = 125,
+	PLDM_ENTITY_DC_MAINS_POWER_SUPPLY = 126,
+
+	/* Chip Entities */
+	PLDM_ENTITY_PROC = 135,
+	PLDM_ENTITY_CHIPSET_COMPONENT = 136,
+	PLDM_ENTITY_MGMT_CONTROLLER = 137,
+	PLDM_ENTITY_PERIPHERAL_CONTROLLER = 138,
+	PLDM_ENTITY_SEEPROM = 139,
+	PLDM_ENTITY_NVRAM_CHIP = 140,
+	PLDM_ENTITY_FLASH_MEMORY_CHIP = 141,
+	PLDM_ENTITY_MEMORY_CHIP = 142,
+	PLDM_ENTITY_MEMORY_CONTROLLER = 143,
+	PLDM_ENTITY_NETWORK_CONTROLLER = 144,
+	PLDM_ENTITY_IO_CONTROLLER = 145,
+	PLDM_ENTITY_SOUTH_BRIDGE = 146,
+	PLDM_ENTITY_REAL_TIME_CLOCK = 147,
+	PLDM_ENTITY_FPGA_CPLD_DEVICE = 148,
+	/* Bus Entities */
+	PLDM_ENTITY_OTHER_BUS = 160,
+	PLDM_ENTITY_SYS_BUS = 161,
+	PLDM_ENTITY_I2C_BUS = 162,
+	PLDM_ENTITY_SMBUS_BUS = 163,
+	PLDM_ENTITY_SPI_BUS = 164,
+	PLDM_ENTITY_PCI_BUS = 165,
+	PLDM_ENTITY_PCI_EXPRESS_BUS = 166,
+	PLDM_ENTITY_PECI_BUS = 167,
+	PLDM_ENTITY_LPC_BUS = 168,
+	PLDM_ENTITY_USB_BUS = 169,
+	PLDM_ENTITY_FIREWIRE_BUS = 170,
+	PLDM_ENTITY_SCSI_BUS = 171,
+	PLDM_ENTITY_SATA_SAS_BUS = 172,
+	PLDM_ENTITY_PROC_FRONT_SIDE_BUS = 173,
+	PLDM_ENTITY_INTER_PROC_BUS = 174,
+
+	/* Connectors/Cables */
+	PLDM_ENTITY_CONNECTOR = 185,
+	PLDM_ENTITY_SLOT = 186,
+	PLDM_ENTITY_CABLE = 187,
+	PLDM_ENTITY_INTERCONNECT = 188,
+	PLDM_ENTITY_PLUG = 189,
+	PLDM_ENTITY_SOCKET = 190,
+
+	/* OEM ranges */
+	PLDM_OEM_ENTITY_TYPE_START = 24576,
+	PLDM_OEM_ENTITY_TYPE_END = 32767,
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ENTITY_H */
diff --git a/include/libpldm/firmware_update.h b/include/libpldm/firmware_update.h
new file mode 100644
index 0000000..0dc5e4b
--- /dev/null
+++ b/include/libpldm/firmware_update.h
@@ -0,0 +1,1132 @@
+#ifndef FW_UPDATE_H
+#define FW_UPDATE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "base.h"
+#include "stdbool.h"
+#include "utils.h"
+
+#define PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE 8
+#define PLDM_FWUP_INVALID_COMPONENT_COMPARISON_TIMESTAMP 0xFFFFFFFF
+#define PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES 0
+/** @brief Minimum length of device descriptor, 2 bytes for descriptor type,
+ *         2 bytes for descriptor length and atleast 1 byte of descriptor data
+ */
+#define PLDM_FWUP_DEVICE_DESCRIPTOR_MIN_LEN 5
+#define PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES 0
+#define PLDM_FWUP_BASELINE_TRANSFER_SIZE 32
+#define PLDM_FWUP_MIN_OUTSTANDING_REQ 1
+#define PLDM_GET_STATUS_REQ_BYTES 0
+/* Maximum progress percentage value*/
+#define PLDM_FWUP_MAX_PROGRESS_PERCENT 0x65
+#define PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES 0
+#define PLDM_CANCEL_UPDATE_REQ_BYTES 0
+
+/** @brief PLDM Firmware update commands
+ */
+enum pldm_firmware_update_commands {
+	PLDM_QUERY_DEVICE_IDENTIFIERS = 0x01,
+	PLDM_GET_FIRMWARE_PARAMETERS = 0x02,
+	PLDM_REQUEST_UPDATE = 0x10,
+	PLDM_PASS_COMPONENT_TABLE = 0x13,
+	PLDM_UPDATE_COMPONENT = 0x14,
+	PLDM_REQUEST_FIRMWARE_DATA = 0x15,
+	PLDM_TRANSFER_COMPLETE = 0x16,
+	PLDM_VERIFY_COMPLETE = 0x17,
+	PLDM_APPLY_COMPLETE = 0x18,
+	PLDM_ACTIVATE_FIRMWARE = 0x1A,
+	PLDM_GET_STATUS = 0x1B,
+	PLDM_CANCEL_UPDATE_COMPONENT = 0x1C,
+	PLDM_CANCEL_UPDATE = 0x1D
+};
+
+/** @brief PLDM Firmware update completion codes
+ */
+enum pldm_firmware_update_completion_codes {
+	PLDM_FWUP_NOT_IN_UPDATE_MODE = 0x80,
+	PLDM_FWUP_ALREADY_IN_UPDATE_MODE = 0x81,
+	PLDM_FWUP_DATA_OUT_OF_RANGE = 0x82,
+	PLDM_FWUP_INVALID_TRANSFER_LENGTH = 0x83,
+	PLDM_FWUP_INVALID_STATE_FOR_COMMAND = 0x84,
+	PLDM_FWUP_INCOMPLETE_UPDATE = 0x85,
+	PLDM_FWUP_BUSY_IN_BACKGROUND = 0x86,
+	PLDM_FWUP_CANCEL_PENDING = 0x87,
+	PLDM_FWUP_COMMAND_NOT_EXPECTED = 0x88,
+	PLDM_FWUP_RETRY_REQUEST_FW_DATA = 0x89,
+	PLDM_FWUP_UNABLE_TO_INITIATE_UPDATE = 0x8A,
+	PLDM_FWUP_ACTIVATION_NOT_REQUIRED = 0x8B,
+	PLDM_FWUP_SELF_CONTAINED_ACTIVATION_NOT_PERMITTED = 0x8C,
+	PLDM_FWUP_NO_DEVICE_METADATA = 0x8D,
+	PLDM_FWUP_RETRY_REQUEST_UPDATE = 0x8E,
+	PLDM_FWUP_NO_PACKAGE_DATA = 0x8F,
+	PLDM_FWUP_INVALID_TRANSFER_HANDLE = 0x90,
+	PLDM_FWUP_INVALID_TRANSFER_OPERATION_FLAG = 0x91,
+	PLDM_FWUP_ACTIVATE_PENDING_IMAGE_NOT_PERMITTED = 0x92,
+	PLDM_FWUP_PACKAGE_DATA_ERROR = 0x93
+};
+
+/** @brief String type values defined in the PLDM firmware update specification
+ */
+enum pldm_firmware_update_string_type {
+	PLDM_STR_TYPE_UNKNOWN = 0,
+	PLDM_STR_TYPE_ASCII = 1,
+	PLDM_STR_TYPE_UTF_8 = 2,
+	PLDM_STR_TYPE_UTF_16 = 3,
+	PLDM_STR_TYPE_UTF_16LE = 4,
+	PLDM_STR_TYPE_UTF_16BE = 5
+};
+
+/** @brief Descriptor types defined in PLDM firmware update specification
+ */
+enum pldm_firmware_update_descriptor_types {
+	PLDM_FWUP_PCI_VENDOR_ID = 0x0000,
+	PLDM_FWUP_IANA_ENTERPRISE_ID = 0x0001,
+	PLDM_FWUP_UUID = 0x0002,
+	PLDM_FWUP_PNP_VENDOR_ID = 0x0003,
+	PLDM_FWUP_ACPI_VENDOR_ID = 0x0004,
+	PLDM_FWUP_IEEE_ASSIGNED_COMPANY_ID = 0x0005,
+	PLDM_FWUP_SCSI_VENDOR_ID = 0x0006,
+	PLDM_FWUP_PCI_DEVICE_ID = 0x0100,
+	PLDM_FWUP_PCI_SUBSYSTEM_VENDOR_ID = 0x0101,
+	PLDM_FWUP_PCI_SUBSYSTEM_ID = 0x0102,
+	PLDM_FWUP_PCI_REVISION_ID = 0x0103,
+	PLDM_FWUP_PNP_PRODUCT_IDENTIFIER = 0x0104,
+	PLDM_FWUP_ACPI_PRODUCT_IDENTIFIER = 0x0105,
+	PLDM_FWUP_ASCII_MODEL_NUMBER_LONG_STRING = 0x0106,
+	PLDM_FWUP_ASCII_MODEL_NUMBER_SHORT_STRING = 0x0107,
+	PLDM_FWUP_SCSI_PRODUCT_ID = 0x0108,
+	PLDM_FWUP_UBM_CONTROLLER_DEVICE_CODE = 0x0109,
+	PLDM_FWUP_VENDOR_DEFINED = 0xFFFF
+};
+
+/** @brief Descriptor types length defined in PLDM firmware update specification
+ */
+enum pldm_firmware_update_descriptor_types_length {
+	PLDM_FWUP_PCI_VENDOR_ID_LENGTH = 2,
+	PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH = 4,
+	PLDM_FWUP_UUID_LENGTH = 16,
+	PLDM_FWUP_PNP_VENDOR_ID_LENGTH = 3,
+	PLDM_FWUP_ACPI_VENDOR_ID_LENGTH = 4,
+	PLDM_FWUP_IEEE_ASSIGNED_COMPANY_ID_LENGTH = 3,
+	PLDM_FWUP_SCSI_VENDOR_ID_LENGTH = 8,
+	PLDM_FWUP_PCI_DEVICE_ID_LENGTH = 2,
+	PLDM_FWUP_PCI_SUBSYSTEM_VENDOR_ID_LENGTH = 2,
+	PLDM_FWUP_PCI_SUBSYSTEM_ID_LENGTH = 2,
+	PLDM_FWUP_PCI_REVISION_ID_LENGTH = 1,
+	PLDM_FWUP_PNP_PRODUCT_IDENTIFIER_LENGTH = 4,
+	PLDM_FWUP_ACPI_PRODUCT_IDENTIFIER_LENGTH = 4,
+	PLDM_FWUP_ASCII_MODEL_NUMBER_LONG_STRING_LENGTH = 40,
+	PLDM_FWUP_ASCII_MODEL_NUMBER_SHORT_STRING_LENGTH = 10,
+	PLDM_FWUP_SCSI_PRODUCT_ID_LENGTH = 16,
+	PLDM_FWUP_UBM_CONTROLLER_DEVICE_CODE_LENGTH = 4
+};
+
+/** @brief ComponentClassification values defined in firmware update
+ *         specification
+ */
+enum pldm_component_classification_values {
+	PLDM_COMP_UNKNOWN = 0x0000,
+	PLDM_COMP_OTHER = 0x0001,
+	PLDM_COMP_DRIVER = 0x0002,
+	PLDM_COMP_CONFIGURATION_SOFTWARE = 0x0003,
+	PLDM_COMP_APPLICATION_SOFTWARE = 0x0004,
+	PLDM_COMP_INSTRUMENTATION = 0x0005,
+	PLDM_COMP_FIRMWARE_OR_BIOS = 0x0006,
+	PLDM_COMP_DIAGNOSTIC_SOFTWARE = 0x0007,
+	PLDM_COMP_OPERATING_SYSTEM = 0x0008,
+	PLDM_COMP_MIDDLEWARE = 0x0009,
+	PLDM_COMP_FIRMWARE = 0x000A,
+	PLDM_COMP_BIOS_OR_FCODE = 0x000B,
+	PLDM_COMP_SUPPORT_OR_SERVICEPACK = 0x000C,
+	PLDM_COMP_SOFTWARE_BUNDLE = 0x000D,
+	PLDM_COMP_DOWNSTREAM_DEVICE = 0xFFFF
+};
+
+/** @brief ComponentActivationMethods is the bit position in the bitfield that
+ *         provides the capability of the FD for firmware activation. Multiple
+ *         activation methods can be supported.
+ */
+enum pldm_comp_activation_methods {
+	PLDM_ACTIVATION_AUTOMATIC = 0,
+	PLDM_ACTIVATION_SELF_CONTAINED = 1,
+	PLDM_ACTIVATION_MEDIUM_SPECIFIC_RESET = 2,
+	PLDM_ACTIVATION_SYSTEM_REBOOT = 3,
+	PLDM_ACTIVATION_DC_POWER_CYCLE = 4,
+	PLDM_ACTIVATION_AC_POWER_CYCLE = 5,
+	PLDM_SUPPORTS_ACTIVATE_PENDING_IMAGE = 6,
+	PLDM_SUPPORTS_ACTIVATE_PENDING_IMAGE_SET = 7
+};
+
+/** @brief ComponentResponse values in the response of PassComponentTable
+ */
+enum pldm_component_responses {
+	PLDM_CR_COMP_CAN_BE_UPDATED = 0,
+	PLDM_CR_COMP_MAY_BE_UPDATEABLE = 1
+};
+
+/** @brief ComponentResponseCode values in the response of PassComponentTable
+ */
+enum pldm_component_response_codes {
+	PLDM_CRC_COMP_CAN_BE_UPDATED = 0x00,
+	PLDM_CRC_COMP_COMPARISON_STAMP_IDENTICAL = 0x01,
+	PLDM_CRC_COMP_COMPARISON_STAMP_LOWER = 0x02,
+	PLDM_CRC_INVALID_COMP_COMPARISON_STAMP = 0x03,
+	PLDM_CRC_COMP_CONFLICT = 0x04,
+	PLDM_CRC_COMP_PREREQUISITES_NOT_MET = 0x05,
+	PLDM_CRC_COMP_NOT_SUPPORTED = 0x06,
+	PLDM_CRC_COMP_SECURITY_RESTRICTIONS = 0x07,
+	PLDM_CRC_INCOMPLETE_COMP_IMAGE_SET = 0x08,
+	PLDM_CRC_ACTIVE_IMAGE_NOT_UPDATEABLE_SUBSEQUENTLY = 0x09,
+	PLDM_CRC_COMP_VER_STR_IDENTICAL = 0x0A,
+	PLDM_CRC_COMP_VER_STR_LOWER = 0x0B,
+	PLDM_CRC_VENDOR_COMP_RESP_CODE_RANGE_MIN = 0xD0,
+	PLDM_CRC_VENDOR_COMP_RESP_CODE_RANGE_MAX = 0xEF
+};
+
+/** @brief ComponentCompatibilityResponse values in the response of
+ *         UpdateComponent
+ */
+enum pldm_component_compatibility_responses {
+	PLDM_CCR_COMP_CAN_BE_UPDATED = 0,
+	PLDM_CCR_COMP_CANNOT_BE_UPDATED = 1
+};
+
+/** @brief ComponentCompatibilityResponse Code values in the response of
+ *         UpdateComponent
+ */
+enum pldm_component_compatibility_response_codes {
+	PLDM_CCRC_NO_RESPONSE_CODE = 0x00,
+	PLDM_CCRC_COMP_COMPARISON_STAMP_IDENTICAL = 0x01,
+	PLDM_CCRC_COMP_COMPARISON_STAMP_LOWER = 0x02,
+	PLDM_CCRC_INVALID_COMP_COMPARISON_STAMP = 0x03,
+	PLDM_CCRC_COMP_CONFLICT = 0x04,
+	PLDM_CCRC_COMP_PREREQUISITES_NOT_MET = 0x05,
+	PLDM_CCRC_COMP_NOT_SUPPORTED = 0x06,
+	PLDM_CCRC_COMP_SECURITY_RESTRICTIONS = 0x07,
+	PLDM_CCRC_INCOMPLETE_COMP_IMAGE_SET = 0x08,
+	PLDM_CCRC_COMP_INFO_NO_MATCH = 0x09,
+	PLDM_CCRC_COMP_VER_STR_IDENTICAL = 0x0A,
+	PLDM_CCRC_COMP_VER_STR_LOWER = 0x0B,
+	PLDM_CCRC_VENDOR_COMP_RESP_CODE_RANGE_MIN = 0xD0,
+	PLDM_CCRC_VENDOR_COMP_RESP_CODE_RANGE_MAX = 0xEF
+};
+
+/** @brief Common error codes in TransferComplete, VerifyComplete and
+ *        ApplyComplete request
+ */
+enum pldm_firmware_update_common_error_codes {
+	PLDM_FWUP_TIME_OUT = 0x09,
+	PLDM_FWUP_GENERIC_ERROR = 0x0A
+};
+
+/** @brief TransferResult values in the request of TransferComplete
+ */
+enum pldm_firmware_update_transfer_result_values {
+	PLDM_FWUP_TRANSFER_SUCCESS = 0x00,
+	PLDM_FWUP_TRANSFER_ERROR_IMAGE_CORRUPT = 0x02,
+	PLDM_FWUP_TRANSFER_ERROR_VERSION_MISMATCH = 0x02,
+	PLDM_FWUP_FD_ABORTED_TRANSFER = 0x03,
+	PLDM_FWUP_FD_ABORTED_TRANSFER_LOW_POWER_STATE = 0x0B,
+	PLDM_FWUP_FD_ABORTED_TRANSFER_RESET_NEEDED = 0x0C,
+	PLDM_FWUP_FD_ABORTED_TRANSFER_STORAGE_ISSUE = 0x0D,
+	PLDM_FWUP_VENDOR_TRANSFER_RESULT_RANGE_MIN = 0x70,
+	PLDM_FWUP_VENDOR_TRANSFER_RESULT_RANGE_MAX = 0x8F
+};
+
+/**@brief VerifyResult values in the request of VerifyComplete
+ */
+enum pldm_firmware_update_verify_result_values {
+	PLDM_FWUP_VERIFY_SUCCESS = 0x00,
+	PLDM_FWUP_VERIFY_ERROR_VERIFICATION_FAILURE = 0x01,
+	PLDM_FWUP_VERIFY_ERROR_VERSION_MISMATCH = 0x02,
+	PLDM_FWUP_VERIFY_FAILED_FD_SECURITY_CHECKS = 0x03,
+	PLDM_FWUP_VERIFY_ERROR_IMAGE_INCOMPLETE = 0x04,
+	PLDM_FWUP_VENDOR_VERIFY_RESULT_RANGE_MIN = 0x90,
+	PLDM_FWUP_VENDOR_VERIFY_RESULT_RANGE_MAX = 0xAF
+};
+
+/**@brief ApplyResult values in the request of ApplyComplete
+ */
+enum pldm_firmware_update_apply_result_values {
+	PLDM_FWUP_APPLY_SUCCESS = 0x00,
+	PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD = 0x01,
+	PLDM_FWUP_APPLY_FAILURE_MEMORY_ISSUE = 0x02,
+	PLDM_FWUP_VENDOR_APPLY_RESULT_RANGE_MIN = 0xB0,
+	PLDM_FWUP_VENDOR_APPLY_RESULT_RANGE_MAX = 0xCF
+};
+
+/** @brief SelfContainedActivationRequest in the request of ActivateFirmware
+ */
+enum pldm_self_contained_activation_req {
+	PLDM_NOT_ACTIVATE_SELF_CONTAINED_COMPONENTS = false,
+	PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS = true
+};
+
+/** @brief Current state/previous state of the FD or FDP returned in GetStatus
+ *         response
+ */
+enum pldm_firmware_device_states {
+	PLDM_FD_STATE_IDLE = 0,
+	PLDM_FD_STATE_LEARN_COMPONENTS = 1,
+	PLDM_FD_STATE_READY_XFER = 2,
+	PLDM_FD_STATE_DOWNLOAD = 3,
+	PLDM_FD_STATE_VERIFY = 4,
+	PLDM_FD_STATE_APPLY = 5,
+	PLDM_FD_STATE_ACTIVATE = 6
+};
+
+/** @brief Firmware device aux state in GetStatus response
+ */
+enum pldm_get_status_aux_states {
+	PLDM_FD_OPERATION_IN_PROGRESS = 0,
+	PLDM_FD_OPERATION_SUCCESSFUL = 1,
+	PLDM_FD_OPERATION_FAILED = 2,
+	PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER = 3
+};
+
+/** @brief Firmware device aux state status in GetStatus response
+ */
+enum pldm_get_status_aux_state_status_values {
+	PLDM_FD_AUX_STATE_IN_PROGRESS_OR_SUCCESS = 0x00,
+	PLDM_FD_TIMEOUT = 0x09,
+	PLDM_FD_GENERIC_ERROR = 0x0A,
+	PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START = 0x70,
+	PLDM_FD_VENDOR_DEFINED_STATUS_CODE_END = 0xEF
+};
+
+/** @brief Firmware device reason code in GetStatus response
+ */
+enum pldm_get_status_reason_code_values {
+	PLDM_FD_INITIALIZATION = 0,
+	PLDM_FD_ACTIVATE_FW = 1,
+	PLDM_FD_CANCEL_UPDATE = 2,
+	PLDM_FD_TIMEOUT_LEARN_COMPONENT = 3,
+	PLDM_FD_TIMEOUT_READY_XFER = 4,
+	PLDM_FD_TIMEOUT_DOWNLOAD = 5,
+	PLDM_FD_TIMEOUT_VERIFY = 6,
+	PLDM_FD_TIMEOUT_APPLY = 7,
+	PLDM_FD_STATUS_VENDOR_DEFINED_MIN = 200,
+	PLDM_FD_STATUS_VENDOR_DEFINED_MAX = 255
+};
+
+/** @brief Components functional indicator in CancelUpdate response
+ */
+enum pldm_firmware_update_non_functioning_component_indication {
+	PLDM_FWUP_COMPONENTS_FUNCTIONING = 0,
+	PLDM_FWUP_COMPONENTS_NOT_FUNCTIONING = 1
+};
+
+/** @struct pldm_package_header_information
+ *
+ *  Structure representing fixed part of package header information
+ */
+struct pldm_package_header_information {
+	uint8_t uuid[PLDM_FWUP_UUID_LENGTH];
+	uint8_t package_header_format_version;
+	uint16_t package_header_size;
+	uint8_t package_release_date_time[PLDM_TIMESTAMP104_SIZE];
+	uint16_t component_bitmap_bit_length;
+	uint8_t package_version_string_type;
+	uint8_t package_version_string_length;
+} __attribute__((packed));
+
+/** @struct pldm_firmware_device_id_record
+ *
+ *  Structure representing firmware device ID record
+ */
+struct pldm_firmware_device_id_record {
+	uint16_t record_length;
+	uint8_t descriptor_count;
+	bitfield32_t device_update_option_flags;
+	uint8_t comp_image_set_version_string_type;
+	uint8_t comp_image_set_version_string_length;
+	uint16_t fw_device_pkg_data_length;
+} __attribute__((packed));
+
+/** @struct pldm_descriptor_tlv
+ *
+ *  Structure representing descriptor type, length and value
+ */
+struct pldm_descriptor_tlv {
+	uint16_t descriptor_type;
+	uint16_t descriptor_length;
+	uint8_t descriptor_data[1];
+} __attribute__((packed));
+
+/** @struct pldm_vendor_defined_descriptor_title_data
+ *
+ *  Structure representing vendor defined descriptor title sections
+ */
+struct pldm_vendor_defined_descriptor_title_data {
+	uint8_t vendor_defined_descriptor_title_str_type;
+	uint8_t vendor_defined_descriptor_title_str_len;
+	uint8_t vendor_defined_descriptor_title_str[1];
+} __attribute__((packed));
+
+/** @struct pldm_component_image_information
+ *
+ *  Structure representing fixed part of individual component information in
+ *  PLDM firmware update package
+ */
+struct pldm_component_image_information {
+	uint16_t comp_classification;
+	uint16_t comp_identifier;
+	uint32_t comp_comparison_stamp;
+	bitfield16_t comp_options;
+	bitfield16_t requested_comp_activation_method;
+	uint32_t comp_location_offset;
+	uint32_t comp_size;
+	uint8_t comp_version_string_type;
+	uint8_t comp_version_string_length;
+} __attribute__((packed));
+
+/** @struct pldm_query_device_identifiers_resp
+ *
+ *  Structure representing query device identifiers response.
+ */
+struct pldm_query_device_identifiers_resp {
+	uint8_t completion_code;
+	uint32_t device_identifiers_len;
+	uint8_t descriptor_count;
+} __attribute__((packed));
+
+/** @struct pldm_get_firmware_parameters_resp
+ *
+ *  Structure representing the fixed part of GetFirmwareParameters response
+ */
+struct pldm_get_firmware_parameters_resp {
+	uint8_t completion_code;
+	bitfield32_t capabilities_during_update;
+	uint16_t comp_count;
+	uint8_t active_comp_image_set_ver_str_type;
+	uint8_t active_comp_image_set_ver_str_len;
+	uint8_t pending_comp_image_set_ver_str_type;
+	uint8_t pending_comp_image_set_ver_str_len;
+} __attribute__((packed));
+
+/** @struct pldm_component_parameter_entry
+ *
+ *  Structure representing component parameter table entry.
+ */
+struct pldm_component_parameter_entry {
+	uint16_t comp_classification;
+	uint16_t comp_identifier;
+	uint8_t comp_classification_index;
+	uint32_t active_comp_comparison_stamp;
+	uint8_t active_comp_ver_str_type;
+	uint8_t active_comp_ver_str_len;
+	uint8_t active_comp_release_date[8];
+	uint32_t pending_comp_comparison_stamp;
+	uint8_t pending_comp_ver_str_type;
+	uint8_t pending_comp_ver_str_len;
+	uint8_t pending_comp_release_date[8];
+	bitfield16_t comp_activation_methods;
+	bitfield32_t capabilities_during_update;
+} __attribute__((packed));
+
+/** @struct pldm_request_update_req
+ *
+ *  Structure representing fixed part of Request Update request
+ */
+struct pldm_request_update_req {
+	uint32_t max_transfer_size;
+	uint16_t num_of_comp;
+	uint8_t max_outstanding_transfer_req;
+	uint16_t pkg_data_len;
+	uint8_t comp_image_set_ver_str_type;
+	uint8_t comp_image_set_ver_str_len;
+} __attribute__((packed));
+
+/** @struct pldm_request_update_resp
+ *
+ *  Structure representing Request Update response
+ */
+struct pldm_request_update_resp {
+	uint8_t completion_code;
+	uint16_t fd_meta_data_len;
+	uint8_t fd_will_send_pkg_data;
+} __attribute__((packed));
+
+/** @struct pldm_pass_component_table_req
+ *
+ *  Structure representing PassComponentTable request
+ */
+struct pldm_pass_component_table_req {
+	uint8_t transfer_flag;
+	uint16_t comp_classification;
+	uint16_t comp_identifier;
+	uint8_t comp_classification_index;
+	uint32_t comp_comparison_stamp;
+	uint8_t comp_ver_str_type;
+	uint8_t comp_ver_str_len;
+} __attribute__((packed));
+
+/** @struct pldm_pass_component_table_resp
+ *
+ *  Structure representing PassComponentTable response
+ */
+struct pldm_pass_component_table_resp {
+	uint8_t completion_code;
+	uint8_t comp_resp;
+	uint8_t comp_resp_code;
+} __attribute__((packed));
+
+/** @struct pldm_update_component_req
+ *
+ *  Structure representing UpdateComponent request
+ */
+struct pldm_update_component_req {
+	uint16_t comp_classification;
+	uint16_t comp_identifier;
+	uint8_t comp_classification_index;
+	uint32_t comp_comparison_stamp;
+	uint32_t comp_image_size;
+	bitfield32_t update_option_flags;
+	uint8_t comp_ver_str_type;
+	uint8_t comp_ver_str_len;
+} __attribute__((packed));
+
+/** @struct pldm_update_component_resp
+ *
+ *  Structure representing UpdateComponent response
+ */
+struct pldm_update_component_resp {
+	uint8_t completion_code;
+	uint8_t comp_compatibility_resp;
+	uint8_t comp_compatibility_resp_code;
+	bitfield32_t update_option_flags_enabled;
+	uint16_t time_before_req_fw_data;
+} __attribute__((packed));
+
+/** @struct pldm_request_firmware_data_req
+ *
+ *  Structure representing RequestFirmwareData request.
+ */
+struct pldm_request_firmware_data_req {
+	uint32_t offset;
+	uint32_t length;
+} __attribute__((packed));
+
+/** @struct pldm_apply_complete_req
+ *
+ *  Structure representing ApplyComplete request.
+ */
+struct pldm_apply_complete_req {
+	uint8_t apply_result;
+	bitfield16_t comp_activation_methods_modification;
+} __attribute__((packed));
+
+/** @struct pldm_activate_firmware_req
+ *
+ *  Structure representing ActivateFirmware request
+ */
+struct pldm_activate_firmware_req {
+	bool8_t self_contained_activation_req;
+} __attribute__((packed));
+
+/** @struct activate_firmware_resp
+ *
+ *  Structure representing Activate Firmware response
+ */
+struct pldm_activate_firmware_resp {
+	uint8_t completion_code;
+	uint16_t estimated_time_activation;
+} __attribute__((packed));
+
+/** @struct pldm_get_status_resp
+ *
+ *  Structure representing GetStatus response.
+ */
+struct pldm_get_status_resp {
+	uint8_t completion_code;
+	uint8_t current_state;
+	uint8_t previous_state;
+	uint8_t aux_state;
+	uint8_t aux_state_status;
+	uint8_t progress_percent;
+	uint8_t reason_code;
+	bitfield32_t update_option_flags_enabled;
+} __attribute__((packed));
+
+/** @struct pldm_cancel_update_resp
+ *
+ *  Structure representing CancelUpdate response.
+ */
+struct pldm_cancel_update_resp {
+	uint8_t completion_code;
+	bool8_t non_functioning_component_indication;
+	uint64_t non_functioning_component_bitmap;
+} __attribute__((packed));
+
+/** @brief Decode the PLDM package header information
+ *
+ *  @param[in] data - pointer to package header information
+ *  @param[in] length - available length in the firmware update package
+ *  @param[out] package_header_info - pointer to fixed part of PLDM package
+ *                                    header information
+ *  @param[out] package_version_str - pointer to package version string
+ *
+ *  @return pldm_completion_codes
+ */
+int decode_pldm_package_header_info(
+    const uint8_t *data, size_t length,
+    struct pldm_package_header_information *package_header_info,
+    struct variable_field *package_version_str);
+
+/** @brief Decode individual firmware device ID record
+ *
+ *  @param[in] data - pointer to firmware device ID record
+ *  @param[in] length - available length in the firmware update package
+ *  @param[in] component_bitmap_bit_length - ComponentBitmapBitLengthfield
+ *                                           parsed from the package header info
+ *  @param[out] fw_device_id_record - pointer to fixed part of firmware device
+ *                                    id record
+ *  @param[out] applicable_components - pointer to ApplicableComponents
+ *  @param[out] comp_image_set_version_str - pointer to
+ *                                           ComponentImageSetVersionString
+ *  @param[out] record_descriptors - pointer to RecordDescriptors
+ *  @param[out] fw_device_pkg_data - pointer to FirmwareDevicePackageData
+ *
+ *  @return pldm_completion_codes
+ */
+int decode_firmware_device_id_record(
+    const uint8_t *data, size_t length, uint16_t component_bitmap_bit_length,
+    struct pldm_firmware_device_id_record *fw_device_id_record,
+    struct variable_field *applicable_components,
+    struct variable_field *comp_image_set_version_str,
+    struct variable_field *record_descriptors,
+    struct variable_field *fw_device_pkg_data);
+
+/** @brief Decode the record descriptor entries in the firmware update package
+ *         and the Descriptors in the QueryDeviceIDentifiers command
+ *
+ *  @param[in] data - pointer to descriptor entry
+ *  @param[in] length - remaining length of the descriptor data
+ *  @param[out] descriptor_type - pointer to descriptor type
+ *  @param[out] descriptor_data - pointer to descriptor data
+ *
+ *  @return pldm_completion_codes
+ */
+int decode_descriptor_type_length_value(const uint8_t *data, size_t length,
+					uint16_t *descriptor_type,
+					struct variable_field *descriptor_data);
+
+/** @brief Decode the vendor defined descriptor value
+ *
+ *  @param[in] data - pointer to vendor defined descriptor value
+ *  @param[in] length - length of the vendor defined descriptor value
+ *  @param[out] descriptor_title_str_type - pointer to vendor defined descriptor
+ *                                          title string type
+ *  @param[out] descriptor_title_str - pointer to vendor defined descriptor
+ *                                     title string
+ *  @param[out] descriptor_data - pointer to vendor defined descriptor data
+ *
+ *  @return pldm_completion_codes
+ */
+int decode_vendor_defined_descriptor_value(
+    const uint8_t *data, size_t length, uint8_t *descriptor_title_str_type,
+    struct variable_field *descriptor_title_str,
+    struct variable_field *descriptor_data);
+
+/** @brief Decode individual component image information
+ *
+ *  @param[in] data - pointer to component image information
+ *  @param[in] length - available length in the firmware update package
+ *  @param[out] pldm_comp_image_info - pointer to fixed part of component image
+ *                                     information
+ *  @param[out] comp_version_str - pointer to component version string
+ *
+ *  @return pldm_completion_codes
+ */
+int decode_pldm_comp_image_info(
+    const uint8_t *data, size_t length,
+    struct pldm_component_image_information *pldm_comp_image_info,
+    struct variable_field *comp_version_str);
+
+/** @brief Create a PLDM request message for QueryDeviceIdentifiers
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] payload_length - Length of the request message payload
+ *  @param[in,out] msg - Message will be written to this
+ *
+ *  @return pldm_completion_codes
+ *
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_query_device_identifiers_req(uint8_t instance_id,
+					size_t payload_length,
+					struct pldm_msg *msg);
+
+/** @brief Decode QueryDeviceIdentifiers response message
+ *
+ *  @param[in] msg - Response message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[out] completion_code - Pointer to response msg's PLDM completion code
+ *  @param[out] device_identifiers_len - Pointer to device identifiers length
+ *  @param[out] descriptor_count - Pointer to descriptor count
+ *  @param[out] descriptor_data - Pointer to descriptor data
+ *
+ *  @return pldm_completion_codes
+ */
+int decode_query_device_identifiers_resp(const struct pldm_msg *msg,
+					 size_t payload_length,
+					 uint8_t *completion_code,
+					 uint32_t *device_identifiers_len,
+					 uint8_t *descriptor_count,
+					 uint8_t **descriptor_data);
+
+/** @brief Create a PLDM request message for GetFirmwareParameters
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] payload_length - Length of the request message payload
+ *  @param[in,out] msg - Message will be written to this
+ *
+ *  @return pldm_completion_codes
+ *
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_get_firmware_parameters_req(uint8_t instance_id,
+				       size_t payload_length,
+				       struct pldm_msg *msg);
+
+/** @brief Decode GetFirmwareParameters response
+ *
+ *  @param[in] msg - Response message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[out] resp_data - Pointer to get firmware parameters response
+ *  @param[out] active_comp_image_set_ver_str - Pointer to active component
+ *                                              image set version string
+ *  @param[out] pending_comp_image_set_ver_str - Pointer to pending component
+ *                                               image set version string
+ *  @param[out] comp_parameter_table - Pointer to component parameter table
+ *
+ *  @return pldm_completion_codes
+ */
+int decode_get_firmware_parameters_resp(
+    const struct pldm_msg *msg, size_t payload_length,
+    struct pldm_get_firmware_parameters_resp *resp_data,
+    struct variable_field *active_comp_image_set_ver_str,
+    struct variable_field *pending_comp_image_set_ver_str,
+    struct variable_field *comp_parameter_table);
+
+/** @brief Decode component entries in the component parameter table which is
+ *         part of the response of GetFirmwareParameters command
+ *
+ *  @param[in] data - Component entry
+ *  @param[in] length - Length of component entry
+ *  @param[out] component_data - Pointer to component parameter table
+ *  @param[out] active_comp_ver_str - Pointer to active component version string
+ *  @param[out] pending_comp_ver_str - Pointer to pending component version
+ *                                     string
+ *
+ *  @return pldm_completion_codes
+ */
+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);
+
+/** @brief Create PLDM request message for RequestUpdate
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] max_transfer_size - Maximum size of the variable payload allowed
+ *                                 to be requested via RequestFirmwareData
+ *                                 command
+ *  @param[in] num_of_comp - Total number of components that will be passed to
+ *                           the FD during the update
+ *  @param[in] max_outstanding_transfer_req - Total number of outstanding
+ * 											  RequestFirmwareData
+ * commands that can be sent by the FD
+ *  @param[in] pkg_data_len - Value of the FirmwareDevicePackageDataLength field
+ *                            present in firmware package header
+ *  @param[in] comp_image_set_ver_str_type - StringType of
+ *                                           ComponentImageSetVersionString
+ *  @param[in] comp_image_set_ver_str_len - The length of the
+ *                                          ComponentImageSetVersionString
+ *  @param[in] comp_img_set_ver_str - Component Image Set version information
+ *  @param[in,out] msg - Message will be written to this
+ *  @param[in] payload_length - Length of request message payload
+ *
+ *  @return pldm_completion_codes
+ *
+ *  @note Caller is responsible for memory alloc and dealloc of param
+ *        'msg.payload'
+ */
+int encode_request_update_req(uint8_t instance_id, uint32_t max_transfer_size,
+			      uint16_t num_of_comp,
+			      uint8_t max_outstanding_transfer_req,
+			      uint16_t pkg_data_len,
+			      uint8_t comp_image_set_ver_str_type,
+			      uint8_t comp_image_set_ver_str_len,
+			      const struct variable_field *comp_img_set_ver_str,
+			      struct pldm_msg *msg, size_t payload_length);
+
+/** @brief Decode a RequestUpdate response message
+ *
+ *  @param[in] msg - Response message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[out] completion_code - Pointer to hold the completion code
+ *  @param[out] fd_meta_data_len - Pointer to hold the length of FD metadata
+ *  @param[out] fd_will_send_pkg_data - Pointer to hold information whether FD
+ *                                      will send GetPackageData command
+ *  @return pldm_completion_codes
+ */
+int decode_request_update_resp(const struct pldm_msg *msg,
+			       size_t payload_length, uint8_t *completion_code,
+			       uint16_t *fd_meta_data_len,
+			       uint8_t *fd_will_send_pkg_data);
+
+/** @brief Create PLDM request message for PassComponentTable
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] transfer_flag - TransferFlag
+ *  @param[in] comp_classification - ComponentClassification
+ *  @param[in] comp_identifier - ComponentIdentifier
+ *  @param[in] comp_classification_index - ComponentClassificationIndex
+ *  @param[in] comp_comparison_stamp - ComponentComparisonStamp
+ *  @param[in] comp_ver_str_type - ComponentVersionStringType
+ *  @param[in] comp_ver_str_len - ComponentVersionStringLength
+ *  @param[in] comp_ver_str - ComponentVersionString
+ *  @param[in,out] msg - Message will be written to this
+ *  @param[in] payload_length - Length of request message payload
+ *                              information
+ *
+ *  @return pldm_completion_codes
+ *
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_pass_component_table_req(
+    uint8_t instance_id, uint8_t transfer_flag, uint16_t comp_classification,
+    uint16_t comp_identifier, uint8_t comp_classification_index,
+    uint32_t comp_comparison_stamp, uint8_t comp_ver_str_type,
+    uint8_t comp_ver_str_len, const struct variable_field *comp_ver_str,
+    struct pldm_msg *msg, size_t payload_length);
+
+/** @brief Decode PassComponentTable response message
+ *
+ *  @param[in] msg - Response message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[out] completion_code - Pointer to hold completion code
+ *  @param[out] comp_resp - Pointer to hold component response
+ *  @param[out] comp_resp_code - Pointer to hold component response code
+ *
+ *  @return pldm_completion_codes
+ */
+int decode_pass_component_table_resp(const struct pldm_msg *msg,
+				     size_t payload_length,
+				     uint8_t *completion_code,
+				     uint8_t *comp_resp,
+				     uint8_t *comp_resp_code);
+
+/** @brief Create PLDM request message for UpdateComponent
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] comp_classification - ComponentClassification
+ *  @param[in] comp_identifier - ComponentIdentifier
+ *  @param[in] comp_classification_index - ComponentClassificationIndex
+ *  @param[in] comp_comparison_stamp - ComponentComparisonStamp
+ *  @param[in] comp_image_size - ComponentImageSize
+ *  @param[in] update_option_flags - UpdateOptionFlags
+ *  @param[in] comp_ver_str_type - ComponentVersionStringType
+ *  @param[in] comp_ver_str_len - ComponentVersionStringLength
+ *  @param[in] comp_ver_str - ComponentVersionString
+ *  @param[in,out] msg - Message will be written to this
+ *  @param[in] payload_length - Length of request message payload
+ *                              information
+ *
+ *  @return pldm_completion_codes
+ *
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_update_component_req(
+    uint8_t instance_id, uint16_t comp_classification, uint16_t comp_identifier,
+    uint8_t comp_classification_index, uint32_t comp_comparison_stamp,
+    uint32_t comp_image_size, bitfield32_t update_option_flags,
+    uint8_t comp_ver_str_type, uint8_t comp_ver_str_len,
+    const struct variable_field *comp_ver_str, struct pldm_msg *msg,
+    size_t payload_length);
+
+/** @brief Decode UpdateComponent response message
+ *
+ *  @param[in] msg - Response message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[out] completion_code - Pointer to hold completion code
+ *  @param[out] comp_compatibility_resp - Pointer to hold component
+ *                                        compatibility response
+ *  @param[out] comp_compatibility_resp_code - Pointer to hold component
+ *                                             compatibility response code
+ *  @param[out] update_option_flags_enabled - Pointer to hold
+ *                                            UpdateOptionsFlagEnabled
+ *  @param[out] time_before_req_fw_data - Pointer to hold the estimated time
+ *                                        before sending RequestFirmwareData
+ *
+ *  @return pldm_completion_codes
+ */
+int decode_update_component_resp(const struct pldm_msg *msg,
+				 size_t payload_length,
+				 uint8_t *completion_code,
+				 uint8_t *comp_compatibility_resp,
+				 uint8_t *comp_compatibility_resp_code,
+				 bitfield32_t *update_option_flags_enabled,
+				 uint16_t *time_before_req_fw_data);
+
+/** @brief Decode RequestFirmwareData request message
+ *
+ *	@param[in] msg - Request message
+ *	@param[in] payload_length - Length of request message payload
+ *	@param[out] offset - Pointer to hold offset
+ *	@param[out] length - Pointer to hold the size of the component image
+ *                       segment requested by the FD/FDP
+ *
+ *	@return pldm_completion_codes
+ */
+int decode_request_firmware_data_req(const struct pldm_msg *msg,
+				     size_t payload_length, uint32_t *offset,
+				     uint32_t *length);
+
+/** @brief Create PLDM response message for RequestFirmwareData
+ *
+ *  The ComponentImagePortion is not encoded in the PLDM response message
+ *  by encode_request_firmware_data_resp to avoid an additional copy. Populating
+ *  ComponentImagePortion in the PLDM response message is handled by the user
+ *  of this API. The payload_length validation considers only the
+ *  CompletionCode.
+ *
+ *	@param[in] instance_id - Message's instance id
+ *	@param[in] completion_code - CompletionCode
+ *	@param[in,out] msg - Message will be written to this
+ *  @param[in] payload_length - Length of response message payload
+ *
+ *	@return pldm_completion_codes
+ *
+ *	@note  Caller is responsible for memory alloc and dealloc of param
+ *		   'msg.payload'
+ */
+int encode_request_firmware_data_resp(uint8_t instance_id,
+				      uint8_t completion_code,
+				      struct pldm_msg *msg,
+				      size_t payload_length);
+
+/** @brief Decode TransferComplete request message
+ *
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - Length of request message payload
+ *  @param[out] transfer_result - Pointer to hold TransferResult
+ *
+ *  @return pldm_completion_codes
+ */
+int decode_transfer_complete_req(const struct pldm_msg *msg,
+				 size_t payload_length,
+				 uint8_t *transfer_result);
+
+/** @brief Create PLDM response message for TransferComplete
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - CompletionCode
+ *  @param[in,out] msg - Message will be written to this
+ *  @param[in] payload_length - Length of response message payload
+ *
+ *  @return pldm_completion_codes
+ *
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_transfer_complete_resp(uint8_t instance_id, uint8_t completion_code,
+				  struct pldm_msg *msg, size_t payload_length);
+
+/** @brief Decode VerifyComplete request message
+ *
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - Length of request message payload
+ *  @param[in] verify_result - Pointer to hold VerifyResult
+ *
+ *  @return pldm_completion_codes
+ */
+int decode_verify_complete_req(const struct pldm_msg *msg,
+			       size_t payload_length, uint8_t *verify_result);
+
+/** @brief Create PLDM response message for VerifyComplete
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - CompletionCode
+ *  @param[in,out] msg - Message will be written to this
+ *  @param[in] payload_length - Length of response message payload
+ *
+ *  @return pldm_completion_codes
+ *
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_verify_complete_resp(uint8_t instance_id, uint8_t completion_code,
+				struct pldm_msg *msg, size_t payload_length);
+
+/** @brief Decode ApplyComplete request message
+ *
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - Length of request message payload
+ *  @param[in] apply_result - Pointer to hold ApplyResult
+ *  @param[in] comp_activation_methods_modification - Pointer to hold the
+ *                                        ComponentActivationMethodsModification
+ *
+ *  @return pldm_completion_codes
+ */
+int decode_apply_complete_req(
+    const struct pldm_msg *msg, size_t payload_length, uint8_t *apply_result,
+    bitfield16_t *comp_activation_methods_modification);
+
+/** @brief Create PLDM response message for ApplyComplete
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - CompletionCode
+ *  @param[in,out] msg - Message will be written to this
+ *  @param[in] payload_length - Length of response message payload
+ *
+ *  @return pldm_completion_codes
+ *
+ *  @note Caller is responsible for memory alloc and dealloc of param
+ *        'msg.payload'
+ */
+int encode_apply_complete_resp(uint8_t instance_id, uint8_t completion_code,
+			       struct pldm_msg *msg, size_t payload_length);
+
+/** @brief Create PLDM request message for ActivateFirmware
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] self_contained_activation_req SelfContainedActivationRequest
+ *  @param[in,out] msg - Message will be written to this
+ *  @param[in] payload_length - Length of request message payload
+ *
+ *  @return pldm_completion_codes
+ *
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_activate_firmware_req(uint8_t instance_id,
+				 bool8_t self_contained_activation_req,
+				 struct pldm_msg *msg, size_t payload_length);
+
+/** @brief Decode ActivateFirmware response message
+ *
+ *  @param[in] msg - Response message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[out] completion_code - Pointer to hold CompletionCode
+ *  @param[out] estimated_time_activation - Pointer to hold
+ *                                       EstimatedTimeForSelfContainedActivation
+ *
+ *  @return pldm_completion_codes
+ */
+int decode_activate_firmware_resp(const struct pldm_msg *msg,
+				  size_t payload_length,
+				  uint8_t *completion_code,
+				  uint16_t *estimated_time_activation);
+
+/** @brief Create PLDM request message for GetStatus
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in,out] msg - Message will be written to this
+ *  @param[in] payload_length - Length of request message payload
+ *
+ *  @return pldm_completion_codes
+ *
+ *  @note Caller is responsible for memory alloc and dealloc of param
+ *        'msg.payload'
+ */
+int encode_get_status_req(uint8_t instance_id, struct pldm_msg *msg,
+			  size_t payload_length);
+
+/** @brief Decode GetStatus response message
+ *
+ *  @param[in] msg - Response message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[out] completion_code - Pointer to completion code
+ *  @param[out] current_state - Pointer to current state machine state
+ *  @param[out] previous_state - Pointer to previous different state machine
+ *                               state
+ *  @param[out] aux_state - Pointer to current operation state of FD/FDP
+ *  @param[out] aux_state_status - Pointer to aux state status
+ *  @param[out] progress_percent - Pointer to progress percentage
+ *  @param[out] reason_code - Pointer to reason for entering current state
+ *  @param[out] update_option_flags_enabled - Pointer to update option flags
+ *                                            enabled
+ *
+ *  @return pldm_completion_codes
+ */
+int decode_get_status_resp(const struct pldm_msg *msg, size_t payload_length,
+			   uint8_t *completion_code, uint8_t *current_state,
+			   uint8_t *previous_state, uint8_t *aux_state,
+			   uint8_t *aux_state_status, uint8_t *progress_percent,
+			   uint8_t *reason_code,
+			   bitfield32_t *update_option_flags_enabled);
+
+/** @brief Create PLDM request message for CancelUpdateComponent
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in,out] msg - Message will be written to this
+ *  @param[in] payload_length - Length of request message payload
+ *
+ *  @return pldm_completion_codes
+ *
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_cancel_update_component_req(uint8_t instance_id,
+				       struct pldm_msg *msg,
+				       size_t payload_length);
+
+/** @brief Decode CancelUpdateComponent response message
+ *
+ *  @param[in] msg - Response message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[out] completion_code - Pointer to the completion code
+ *
+ *  @return pldm_completion_codes
+ */
+int decode_cancel_update_component_resp(const struct pldm_msg *msg,
+					size_t payload_length,
+					uint8_t *completion_code);
+
+/** @brief Create PLDM request message for CancelUpdate
+ *
+ *	@param[in] instance_id - Message's instance id
+ *	@param[in,out] msg - Message will be written to this
+ *  @param[in] payload_length - Length of request message payload
+ *
+ *	@return pldm_completion_codes
+ *
+ *	@note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_cancel_update_req(uint8_t instance_id, struct pldm_msg *msg,
+			     size_t payload_length);
+
+/** @brief Decode CancelUpdate response message
+ *
+ *	@param[in] msg - Response message
+ *  @param[in] payload_length - Length of response message payload
+ *	@param[out] completion_code - Pointer to completion code
+ *	@param[out] non_functioning_component_indication - Pointer to non
+						       functioning
+ *                                                     component indication
+ *	@param[out] non_functioning_component_bitmap - Pointer to non
+ functioning
+ *                                                 component bitmap
+ *
+ *	@return pldm_completion_codes
+ */
+int decode_cancel_update_resp(const struct pldm_msg *msg, size_t payload_length,
+			      uint8_t *completion_code,
+			      bool8_t *non_functioning_component_indication,
+			      bitfield64_t *non_functioning_component_bitmap);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // End of FW_UPDATE_H
diff --git a/include/libpldm/fru.h b/include/libpldm/fru.h
new file mode 100644
index 0000000..bb2f571
--- /dev/null
+++ b/include/libpldm/fru.h
@@ -0,0 +1,507 @@
+#ifndef FRU_H
+#define FRU_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <asm/byteorder.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base.h"
+#include "utils.h"
+
+#define PLDM_GET_FRU_RECORD_TABLE_METADATA_REQ_BYTES 0
+#define PLDM_GET_FRU_RECORD_TABLE_METADATA_RESP_BYTES 19
+#define PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES 5
+#define PLDM_GET_FRU_RECORD_TABLE_MIN_RESP_BYTES 6
+#define PLDM_GET_FRU_RECORD_BY_OPTION_MIN_RESP_BYTES 6
+#define PLDM_SET_FRU_RECORD_TABLE_MIN_REQ_BYTES 5
+#define PLDM_SET_FRU_RECORD_TABLE_RESP_BYTES 5
+
+#define FRU_TABLE_CHECKSUM_SIZE 4
+
+enum pldm_fru_completion_codes {
+	PLDM_FRU_INVALID_DATA_TRANSFER_HANDLE = 0x80,
+	PLDM_FRU_INVALID_TRANSFER_FLAG = 0x82,
+	PLDM_FRU_DATA_INVALID_DATA_INTEGRITY_CHECK = 0x84,
+	PLDM_FRU_DATA_STRUCTURE_TABLE_UNAVAILABLE = 0x85,
+};
+
+/** @brief PLDM FRU commands
+ */
+enum pldm_fru_commands {
+	PLDM_GET_FRU_RECORD_TABLE_METADATA = 0X01,
+	PLDM_GET_FRU_RECORD_TABLE = 0X02,
+	PLDM_SET_FRU_RECORD_TABLE = 0X03,
+	PLDM_GET_FRU_RECORD_BY_OPTION = 0X04
+};
+
+/** @brief FRU record types
+ */
+enum pldm_fru_record_type {
+	PLDM_FRU_RECORD_TYPE_GENERAL = 0X01,
+	PLDM_FRU_RECORD_TYPE_OEM = 0XFE,
+};
+
+/** @brief Encoding type for FRU fields
+ */
+enum pldm_fru_field_encoding {
+	PLDM_FRU_ENCODING_UNSPECIFIED = 0X00,
+	PLDM_FRU_ENCODING_ASCII = 0X01,
+	PLDM_FRU_ENCODING_UTF8 = 0X02,
+	PLDM_FRU_ENCODING_UTF16 = 0X03,
+	PLDM_FRU_ENCODING_UTF16LE = 0X04,
+	PLDM_FRU_ENCODING_UTF16BE = 0X05,
+};
+
+/** @brief FRU field types
+ */
+enum pldm_fru_field_type {
+	PLDM_FRU_FIELD_TYPE_CHASSIS = 0X01,
+	PLDM_FRU_FIELD_TYPE_MODEL = 0X02,
+	PLDM_FRU_FIELD_TYPE_PN = 0X03,
+	PLDM_FRU_FIELD_TYPE_SN = 0X04,
+	PLDM_FRU_FIELD_TYPE_MANUFAC = 0X05,
+	PLDM_FRU_FIELD_TYPE_MANUFAC_DATE = 0X06,
+	PLDM_FRU_FIELD_TYPE_VENDOR = 0X07,
+	PLDM_FRU_FIELD_TYPE_NAME = 0X08,
+	PLDM_FRU_FIELD_TYPE_SKU = 0X09,
+	PLDM_FRU_FIELD_TYPE_VERSION = 0X0A,
+	PLDM_FRU_FIELD_TYPE_ASSET_TAG = 0X0B,
+	PLDM_FRU_FIELD_TYPE_DESC = 0X0C,
+	PLDM_FRU_FIELD_TYPE_EC_LVL = 0X0D,
+	PLDM_FRU_FIELD_TYPE_OTHER = 0X0E,
+	PLDM_FRU_FIELD_TYPE_IANA = 0X0F,
+};
+
+/** @struct pldm_get_fru_record_table_metadata_resp
+ *
+ *  Structure representing PLDM get FRU table metadata response.
+ */
+struct pldm_get_fru_record_table_metadata_resp {
+	uint8_t completion_code;	//!< completion code
+	uint8_t fru_data_major_version; //!< The major version of the FRU Record
+	uint8_t fru_data_minor_version; //!< The minor version of the FRU Record
+	uint32_t
+	    fru_table_maximum_size; //!< The size of the largest FRU Record data
+	uint32_t fru_table_length; //!< The total length of the FRU Record Table
+	uint16_t total_record_set_identifiers; //!< The total number of FRU
+					       //!< Record Data structures
+	uint16_t
+	    total_table_records; //!< The total number of records in the table
+	uint32_t
+	    checksum; //!< The integrity checksum on the FRU Record Table data
+} __attribute__((packed));
+
+/** @struct pldm_get_fru_record_table_req
+ *
+ *  Structure representing PLDM get FRU record table request.
+ */
+struct pldm_get_fru_record_table_req {
+	uint32_t data_transfer_handle;
+	uint8_t transfer_operation_flag;
+} __attribute__((packed));
+
+/** @struct pldm_get_fru_record_table_resp
+ *
+ *  Structure representing PLDM get FRU record table response.
+ */
+struct pldm_get_fru_record_table_resp {
+	uint8_t completion_code;
+	uint32_t next_data_transfer_handle;
+	uint8_t transfer_flag;
+	uint8_t fru_record_table_data[1];
+} __attribute__((packed));
+
+struct pldm_get_fru_record_by_option_req {
+	uint32_t data_transfer_handle;
+	uint16_t fru_table_handle;
+	uint16_t record_set_identifier;
+	uint8_t record_type;
+	uint8_t field_type;
+	uint8_t transfer_op_flag;
+} __attribute__((packed));
+
+struct pldm_get_fru_record_by_option_resp {
+	uint8_t completion_code;
+	uint32_t next_data_transfer_handle;
+	uint8_t transfer_flag;
+	uint8_t fru_structure_data[1];
+} __attribute__((packed));
+
+struct pldm_set_fru_record_table_req {
+	uint32_t data_transfer_handle;
+	uint8_t transfer_flag;
+	uint8_t fru_record_table_data[1];
+} __attribute__((packed));
+
+struct pldm_set_fru_record_table_resp {
+	uint8_t completion_code;
+	uint32_t next_data_transfer_handle;
+} __attribute__((packed));
+
+/** @struct pldm_fru_record_tlv
+ *
+ *  Structure representing each FRU field entry (type, length, value)
+ */
+struct pldm_fru_record_tlv {
+	uint8_t type;
+	uint8_t length;
+	uint8_t value[1];
+} __attribute__((packed));
+
+/** @struct pldm_fru_record_data_format
+ *
+ *  Structure representing the FRU record data format
+ */
+struct pldm_fru_record_data_format {
+	uint16_t record_set_id;
+	uint8_t record_type;
+	uint8_t num_fru_fields;
+	uint8_t encoding_type;
+	struct pldm_fru_record_tlv tlvs[1];
+} __attribute__((packed));
+
+/* Requester */
+
+/* GetFRURecordTableMetadata */
+
+/** @brief Create a PLDM request message for GetFRURecordTableMetadata
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in,out] msg - Message will be written to this
+ *  @param[in] payload_length - Length of the request message payload
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_get_fru_record_table_metadata_req(uint8_t instance_id,
+					     struct pldm_msg *msg,
+					     size_t payload_length);
+
+/** @brief Decode GetFruRecordTable response data
+ *
+ *  Note:
+ *  * If the return value is not PLDM_SUCCESS, it represents a
+ * transport layer error.
+ *  * If the completion_code value is not PLDM_SUCCESS, it represents a
+ * protocol layer error and all the out-parameters are invalid.
+ *
+ *  @param[in] msg - Response message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[out] completion_code - Pointer to response msg's PLDM completion code
+ *  @param[out] fru_data_major_version - Major version of the FRU Record
+ *  @param[out] fru_data_minor_version - Minor version of the FRU Record
+ *  @param[out] fru_table_maximum_size - Size of the largest FRU Record data
+ *  @param[out] fru_table_length - Total length of the FRU Record Table
+ *  @param[out] total_Record_Set_Identifiers - Total number of FRU Record Data
+ * structures
+ *  @param[out] total_table_records - Total number of records in the table
+ *  @param[out] checksum - integrity checksum on the FRU Record Table data
+ *  @return pldm_completion_codes
+ */
+int decode_get_fru_record_table_metadata_resp(
+    const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
+    uint8_t *fru_data_major_version, uint8_t *fru_data_minor_version,
+    uint32_t *fru_table_maximum_size, uint32_t *fru_table_length,
+    uint16_t *total_record_set_identifiers, uint16_t *total_table_records,
+    uint32_t *checksum);
+
+/* Responder */
+
+/* GetFRURecordTableMetadata */
+
+/** @brief Create a PLDM response message for GetFRURecordTableMetadata
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in] fru_data_major_version - Major version of the FRU Record
+ *  @param[in] fru_data_minor_version - Minor version of the FRU Record
+ *  @param[in] fru_table_maximum_size - Size of the largest FRU Record data
+ *  @param[in] fru_table_length - Total length of the FRU Record Table
+ *  @param[in] total_Record_Set_Identifiers - Total number of FRU Record Data
+ * structures
+ *  @param[in] total_table_records - Total number of records in the table
+ *  @param[in] checksum - integrity checksum on the FRU Record Table data
+ *  @param[in,out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+
+int encode_get_fru_record_table_metadata_resp(
+    uint8_t instance_id, uint8_t completion_code,
+    uint8_t fru_data_major_version, uint8_t fru_data_minor_version,
+    uint32_t fru_table_maximum_size, uint32_t fru_table_length,
+    uint16_t total_record_set_identifiers, uint16_t total_table_records,
+    uint32_t checksum, struct pldm_msg *msg);
+
+/* GetFruRecordTable */
+
+/** @brief Decode GetFruRecordTable request data
+ *
+ *  @param[in] msg - PLDM request message payload
+ *  @param[in] payload_length - Length of request payload
+ *  @param[out] data_transfer_handle - A handle, used to identify a FRU Record
+ *  Table data transfer
+ *  @param[out] transfer_operation_flag - A flag that indicates whether this is
+ *  the start of the transfer
+ *  @return pldm_completion_codes
+ */
+int decode_get_fru_record_table_req(const struct pldm_msg *msg,
+				    size_t payload_length,
+				    uint32_t *data_transfer_handle,
+				    uint8_t *transfer_operation_flag);
+
+/** @brief Create a PLDM response message for GetFruRecordTable
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in] next_data_transfer_handle - A handle that is used to identify the
+ *  next portion of the transfer
+ *  @param[in] transfer_flag - The transfer flag that indicates what part of the
+ *  transfer this response represents
+ *  @param[in,out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param 'msg',
+ *         and for appending the FRU table to the msg.
+ */
+int encode_get_fru_record_table_resp(uint8_t instance_id,
+				     uint8_t completion_code,
+				     uint32_t next_data_transfer_handle,
+				     uint8_t transfer_flag,
+				     struct pldm_msg *msg);
+
+/* GetFRURecordByOption */
+
+/** @brief Decode GetFRURecordByOption request data
+ *
+ *  @param[in] msg - PLDM request message payload
+ *  @param[in] payload_length - Length of request payload
+ *  @param[out] data_transfer_handle - A handle, used to identify a FRU Record
+ *              Table data transfer
+ *  @param[out] fru_table_handle - A handle, used to identify a FRU DATA
+ *              records
+ *  @param[out] record_set_identifier - FRU record set identifier
+ *  @param[out] record_type - FRU record type
+ *  @param[out] field_type - FRU field type
+ *  @param[out] transfer_op_flag - A flag that indicates whether this is
+ *              the start of the transfer
+ *  @return pldm_completion_codes
+ */
+int decode_get_fru_record_by_option_req(
+    const struct pldm_msg *msg, size_t payload_length,
+    uint32_t *data_transfer_handle, uint16_t *fru_table_handle,
+    uint16_t *record_set_identifier, uint8_t *record_type, uint8_t *field_type,
+    uint8_t *transfer_op_flag);
+
+/** @brief Encode GetFRURecordByOption response data
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in] next_data_transfer_handle - A handle that is used to identify the
+ *             next portion of the transfer
+ *  @param[in] transfer_flag - The transfer flag that indicates what part of the
+ *             transfer this response represents
+ *  @param[in] fru_structure_data - FRU Structure Data
+ *  @param[in] data_size - Size of FRU Structrue Data
+ *  @param[in,out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param 'msg',
+ *         and for appending the FRU table to the msg.
+ */
+int encode_get_fru_record_by_option_resp(uint8_t instance_id,
+					 uint8_t completion_code,
+					 uint32_t next_data_transfer_handle,
+					 uint8_t transfer_flag,
+					 const void *fru_structure_data,
+					 size_t data_size, struct pldm_msg *msg,
+					 size_t payload_length);
+
+/* Requester */
+
+/* GetFruRecordTable */
+
+/** @brief Create a PLDM request message for GetFruRecordTable
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] data_transfer_handle - A handle, used to identify a FRU Record
+ *  Table data transfer
+ *  @param[in] transfer_operation_flag - A flag that indicates whether this is
+ *  the start of the transfer
+ *  @param[in,out] msg - Message will be written to this
+ *  @param[in] payload_length - Length of request message payload
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+
+int encode_get_fru_record_table_req(uint8_t instance_id,
+				    uint32_t data_transfer_handle,
+				    uint8_t transfer_operation_flag,
+				    struct pldm_msg *msg,
+				    size_t payload_length);
+
+/** @brief Decode GetFruRecordTable response data
+ *
+ *  @param[in] msg - Response message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[out] completion_code - Pointer to response msg's PLDM completion code
+ *  @param[out] next_data_transfer_handle - A handle used to identify the next
+ *  portion of the transfer
+ *  @param[out] transfer_flag - The transfer flag that indicates what part of
+ * the transfer this response represents
+ *  @param[out] fru_record_table_data - This data is a portion of the overall
+ * FRU Record Table
+ *  @param[out] fru_record_table_length - Length of the FRU record table data
+ *  @return pldm_completion_codes
+ */
+
+int decode_get_fru_record_table_resp(
+    const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
+    uint32_t *next_data_transfer_handle, uint8_t *transfer_flag,
+    uint8_t *fru_record_table_data, size_t *fru_record_table_length);
+
+/** @brief Decode GetFruRecordTable response data, ensuring that the fru
+ *         record table section is small enough to fit in the provided buffer.
+ *
+ *  @param[in] msg - Response message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[out] completion_code - Pointer to response msg's PLDM completion code
+ *  @param[out] next_data_transfer_handle - A handle used to identify the next
+ *  portion of the transfer
+ *  @param[out] transfer_flag - The transfer flag that indicates what part of
+ * the transfer this response represents
+ *  @param[out] fru_record_table_data - This data is a portion of the overall
+ * FRU Record Table
+ *  @param[out] fru_record_table_length - Length of the FRU record table data
+ *  @param[in] max_fru_record_table_length - Maximum length of the FRU record
+ * table data. If the response contains more data than this,
+ * return PLDM_ERROR_INVALID_LENGTH.
+ *  @return pldm_completion_codes
+ */
+
+int decode_get_fru_record_table_resp_safe(
+    const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
+    uint32_t *next_data_transfer_handle, uint8_t *transfer_flag,
+    uint8_t *fru_record_table_data, size_t *fru_record_table_length,
+    size_t max_fru_record_table_length);
+
+/** @brief Encode the FRU record in the FRU table
+ *
+ *  @param[in/out] fru_table - Pointer to the FRU table
+ *  @param[in] total_size - The size of the table,including the size of FRU
+ *                          record to be added to the table.
+ *  @param[in/out] curr_size - The size of the table, excluding the size of FRU
+ *                          record to be added to the table.
+ *  @param[in] record_set_id - FRU record set identifier
+ *  @param[in] record_type - FRU record type
+ *  @param[in] num_frus - Number of FRU fields
+ *  @param[in] encoding - Encoding type for FRU fields
+ *  @param[in] tlvs - Pointer to the buffer with all the FRU fields
+ *  @param[in] tlvs_size - Size of the  buffer with all the FRU fields
+ *
+ *  @return pldm_completion_codes
+ */
+int encode_fru_record(uint8_t *fru_table, size_t total_size, size_t *curr_size,
+		      uint16_t record_set_id, uint8_t record_type,
+		      uint8_t num_frus, uint8_t encoding, uint8_t *tlvs,
+		      size_t tlvs_size);
+
+/* GetFRURecordByOption */
+
+/** @brief Create a PLDM request message for GetFRURecordByOption
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] data_transfer_handle - A handle, used to identify a FRU Record
+ *             Table data transfer
+ *  @param[in] fru_table_handle - A handle, used to identify a FRU DATA records
+ *  @param[in] record_set_identifier - FRU record set identifier
+ *  @param[in] record_type - FRU record type
+ *  @param[in] field_type - FRU field type
+ *  @param[in] transfer_op_flag - A flag that indicates whether this is
+ *             the start of the transfer
+ *  @param[in,out] msg - Message will be written to this
+ *  @param[in] payload_length - Length of request message payload
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_get_fru_record_by_option_req(
+    uint8_t instance_id, uint32_t data_transfer_handle,
+    uint16_t fru_table_handle, uint16_t record_set_identifier,
+    uint8_t record_type, uint8_t field_type, uint8_t transfer_op_flag,
+    struct pldm_msg *msg, size_t payload_length);
+
+/** @brief Decode GetFRURecordByOption response data
+ *
+ *  @param[in] msg - Response message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[out] completion_code - Pointer to response msg's PLDM completion code
+ *  @param[out] next_data_transfer_handle - A handle used to identify the next
+ *              portion of the transfer
+ *  @param[out] transfer_flag - The transfer flag that indicates what part of
+ *              the transfer this response represents
+ *  @param[out] fru_structure_data - FRU Structure Data
+ *  @return pldm_completion_codes
+ */
+int decode_get_fru_record_by_option_resp(
+    const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
+    uint32_t *next_transfer_handle, uint8_t *transfer_flag,
+    struct variable_field *fru_structure_data);
+
+/** @brief Get FRU Record Table By Option
+ *  @param[in] table - The source fru record table
+ *  @param[in] table_size - Size of the source fru record table
+ *  @param[out] record_table - Fru table fetched based on the input option
+ *  @param[in/out] record_size - Size of the table fetched by fru record option
+ *  @param[in] rsi - FRU record set identifier
+ *  @param[in] rt - FRU record type
+ *  @param[in] ft - FRU field type
+ */
+void get_fru_record_by_option(const uint8_t *table, size_t table_size,
+			      uint8_t *record_table, size_t *record_size,
+			      uint16_t rsi, uint8_t rt, uint8_t ft);
+/* SetFruRecordTable */
+
+/** @brief Decode SetFruRecordTable request data
+ *
+ *  @param[in] msg - PLDM request message payload
+ *  @param[in] payload_length - Length of request payload
+ *  @param[out] data_transfer_handle - A handle used to identify a FRU Record
+ *                                     table data transfer
+ *  @param[out] transfer_flag - Flag to indicate what part of the transfer
+ *                              this request represents
+ *  @param[out] fru_table_data - Struct variable_field, contains data specific
+ *                               to the fru record table and the length of table
+ *                               data
+ *  @return pldm_completion_codes
+ */
+int decode_set_fru_record_table_req(const struct pldm_msg *msg,
+				    size_t payload_length,
+				    uint32_t *data_transfer_handle,
+				    uint8_t *transfer_flag,
+				    struct variable_field *fru_table_data);
+
+/** @brief Create a PLDM response message for SetFruRecordTable
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in] next_transfer_handle - handle to identify the next portion of the
+ *                                    transfer
+ *  @param[in] payload_length - Length of payload message
+ *  @param[out] msg - Argument to capture the Message
+ */
+int encode_set_fru_record_table_resp(uint8_t instance_id,
+				     uint8_t completion_code,
+				     uint32_t next_data_transfer_handle,
+				     size_t payload_length,
+				     struct pldm_msg *msg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/libpldm/meson.build b/include/libpldm/meson.build
new file mode 100644
index 0000000..0d25754
--- /dev/null
+++ b/include/libpldm/meson.build
@@ -0,0 +1,35 @@
+libpldm_include_dir += include_directories('.')
+
+libpldm_headers += files(
+  'base.h',
+  'pldm_types.h',
+  'platform.h',
+  'bios.h',
+  'bios_table.h',
+  'entity.h',
+  'states.h',
+  'state_set.h',
+  'fru.h',
+  'utils.h',
+  'pdr.h',
+  'firmware_update.h'
+  )
+
+if get_option('oem-ibm').enabled()
+  libpldm_include_dir += include_directories('oem/ibm')
+  libpldm_headers += files(
+    'oem/ibm/libpldm/entity_oem_ibm.h',
+    'oem/ibm/libpldm/file_io.h',
+    'oem/ibm/libpldm/host.h',
+    'oem/ibm/libpldm/fru_oem_ibm.h',
+    'oem/ibm/libpldm/platform_oem_ibm.h',
+    'oem/ibm/libpldm/state_set_oem_ibm.h'
+  )
+endif
+
+if get_option('requester-api').enabled()
+   libpldm_headers += files(
+    'requester/pldm.h'
+    )
+endif
+
diff --git a/include/libpldm/oem/ibm/libpldm/entity_oem_ibm.h b/include/libpldm/oem/ibm/libpldm/entity_oem_ibm.h
new file mode 100644
index 0000000..dd80f56
--- /dev/null
+++ b/include/libpldm/oem/ibm/libpldm/entity_oem_ibm.h
@@ -0,0 +1,17 @@
+#ifndef OEM_IBM_ENTITY_H
+#define OEM_IBM_ENTITY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum pldm_oem_ibm_entity_id_codes {
+	PLDM_OEM_IBM_ENTITY_TPM = 24576,
+	PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE = 24577,
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OEM_IBM_ENTITY_H */
diff --git a/include/libpldm/oem/ibm/libpldm/file_io.h b/include/libpldm/oem/ibm/libpldm/file_io.h
new file mode 100644
index 0000000..c78627f
--- /dev/null
+++ b/include/libpldm/oem/ibm/libpldm/file_io.h
@@ -0,0 +1,901 @@
+#ifndef FILEIO_H
+#define FILEIO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base.h"
+
+/** @brief PLDM Commands in IBM OEM type
+ */
+enum pldm_fileio_commands {
+	PLDM_GET_FILE_TABLE = 0x1,
+	PLDM_READ_FILE = 0x4,
+	PLDM_WRITE_FILE = 0x5,
+	PLDM_READ_FILE_INTO_MEMORY = 0x6,
+	PLDM_WRITE_FILE_FROM_MEMORY = 0x7,
+	PLDM_READ_FILE_BY_TYPE_INTO_MEMORY = 0x8,
+	PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY = 0x9,
+	PLDM_NEW_FILE_AVAILABLE = 0xA,
+	PLDM_READ_FILE_BY_TYPE = 0xB,
+	PLDM_WRITE_FILE_BY_TYPE = 0xC,
+	PLDM_FILE_ACK = 0xD,
+	PLDM_NEW_FILE_AVAILABLE_WITH_META_DATA = 0xE,
+	PLDM_FILE_ACK_WITH_META_DATA = 0xF,
+};
+
+/** @brief PLDM Command specific codes
+ */
+enum pldm_fileio_completion_codes {
+	PLDM_FILE_TABLE_UNAVAILABLE = 0x83,
+	PLDM_INVALID_FILE_TABLE_TYPE = 0x85,
+	PLDM_INVALID_FILE_HANDLE = 0x86,
+	PLDM_DATA_OUT_OF_RANGE = 0x87,
+	PLDM_INVALID_FILE_TYPE = 0x89,
+	PLDM_ERROR_FILE_DISCARDED = 0x8A,
+};
+
+/** @brief PLDM File I/O table types
+ */
+enum pldm_fileio_table_type {
+	PLDM_FILE_ATTRIBUTE_TABLE = 0,
+	PLDM_OEM_FILE_ATTRIBUTE_TABLE = 1,
+};
+
+/** @brief PLDM File I/O table types
+ */
+enum pldm_fileio_file_type {
+	PLDM_FILE_TYPE_PEL = 0x0,
+	PLDM_FILE_TYPE_LID_PERM = 0x1,
+	PLDM_FILE_TYPE_LID_TEMP = 0x2,
+	PLDM_FILE_TYPE_DUMP = 0x3,
+	PLDM_FILE_TYPE_CERT_SIGNING_REQUEST = 0x4,
+	PLDM_FILE_TYPE_SIGNED_CERT = 0x5,
+	PLDM_FILE_TYPE_ROOT_CERT = 0x6,
+	PLDM_FILE_TYPE_LID_MARKER = 0x7,
+	PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS = 0x8,
+	PLDM_FILE_TYPE_RESOURCE_DUMP = 0x9,
+	PLDM_FILE_TYPE_PROGRESS_SRC = 0xA,
+	PLDM_FILE_TYPE_LID_RUNNING = 0x13,
+};
+
+#define PLDM_RW_FILE_MEM_REQ_BYTES 20
+#define PLDM_RW_FILE_MEM_RESP_BYTES 5
+#define PLDM_GET_FILE_TABLE_REQ_BYTES 6
+#define PLDM_GET_FILE_TABLE_MIN_RESP_BYTES 6
+#define PLDM_READ_FILE_REQ_BYTES 12
+#define PLDM_READ_FILE_RESP_BYTES 5
+#define PLDM_WRITE_FILE_REQ_BYTES 12
+#define PLDM_WRITE_FILE_RESP_BYTES 5
+#define PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES 22
+#define PLDM_RW_FILE_BY_TYPE_MEM_RESP_BYTES 5
+#define PLDM_NEW_FILE_REQ_BYTES 14
+#define PLDM_NEW_FILE_RESP_BYTES 1
+#define PLDM_RW_FILE_BY_TYPE_REQ_BYTES 14
+#define PLDM_RW_FILE_BY_TYPE_RESP_BYTES 5
+#define PLDM_FILE_ACK_REQ_BYTES 7
+#define PLDM_FILE_ACK_RESP_BYTES 1
+#define PLDM_FILE_ACK_WITH_META_DATA_REQ_BYTES 23
+#define PLDM_FILE_ACK_WITH_META_DATA_RESP_BYTES 1
+#define PLDM_NEW_FILE_AVAILABLE_WITH_META_DATA_REQ_BYTES 30
+#define PLDM_NEW_FILE_AVAILABLE_WITH_META_DATA_RESP_BYTES 1
+
+/** @struct pldm_read_write_file_memory_req
+ *
+ *  Structure representing ReadFileIntoMemory request and WriteFileFromMemory
+ *  request
+ */
+struct pldm_read_write_file_memory_req {
+	uint32_t file_handle; //!< A Handle to the file
+	uint32_t offset;      //!< Offset to the file
+	uint32_t length;      //!< Number of bytes to be read/write
+	uint64_t address;     //!< Memory address of the file
+} __attribute__((packed));
+
+/** @struct pldm_read_write_file_memory_resp
+ *
+ *  Structure representing ReadFileIntoMemory response and WriteFileFromMemory
+ *  response
+ */
+struct pldm_read_write_file_memory_resp {
+	uint8_t completion_code; //!< completion code
+	uint32_t length;	 //!< Number of bytes read/written
+} __attribute__((packed));
+
+/** @brief Decode ReadFileIntoMemory and WriteFileFromMemory commands request
+ *         data
+ *
+ *  @param[in] msg - Pointer to PLDM request message
+ *  @param[in] payload_length - Length of request payload
+ *  @param[out] file_handle - A handle to the file
+ *  @param[out] offset - Offset to the file at which the read should begin
+ *  @param[out] length - Number of bytes to be read
+ *  @param[out] address - Memory address where the file content has to be
+ *                        written to
+ *  @return pldm_completion_codes
+ */
+int decode_rw_file_memory_req(const struct pldm_msg *msg, size_t payload_length,
+			      uint32_t *file_handle, uint32_t *offset,
+			      uint32_t *length, uint64_t *address);
+
+/** @brief Create a PLDM response for ReadFileIntoMemory and
+ *         WriteFileFromMemory
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] command - PLDM command
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in] length - Number of bytes read. This could be less than what the
+			 requester asked for.
+ *  @param[in,out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param 'msg'
+ */
+int encode_rw_file_memory_resp(uint8_t instance_id, uint8_t command,
+			       uint8_t completion_code, uint32_t length,
+			       struct pldm_msg *msg);
+
+/** @brief Encode ReadFileIntoMemory and WriteFileFromMemory
+ *         commands request data
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] command - PLDM command
+ *  @param[in] file_handle - A handle to the file
+ *  @param[in] offset -  Offset to the file at which the read should begin
+ *  @param[in] length -  Number of bytes to be read/written
+ *  @param[in] address - Memory address where the file content has to be
+ *                       written to
+ *  @param[out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ */
+int encode_rw_file_memory_req(uint8_t instance_id, uint8_t command,
+			      uint32_t file_handle, uint32_t offset,
+			      uint32_t length, uint64_t address,
+			      struct pldm_msg *msg);
+
+/** @brief Decode ReadFileIntoMemory and WriteFileFromMemory
+ *         commands response data
+ *
+ *  @param[in] msg - pointer to PLDM response message
+ *  @param[in] payload_length - Length of response payload
+ *  @param[out] completion_code - PLDM completion code
+ *  @param[out] length - Number of bytes to be read/written
+ *  @return pldm_completion_codes
+ */
+int decode_rw_file_memory_resp(const struct pldm_msg *msg,
+			       size_t payload_length, uint8_t *completion_code,
+			       uint32_t *length);
+
+/** @struct pldm_get_file_table_req
+ *
+ *  Structure representing GetFileTable request
+ */
+struct pldm_get_file_table_req {
+	uint32_t transfer_handle; //!< Data transfer handle
+	uint8_t operation_flag;	  //!< Transfer operation flag
+	uint8_t table_type;	  //!< Table type
+} __attribute__((packed));
+
+/** @struct pldm_get_file_table_resp
+ *
+ *  Structure representing GetFileTable response fixed data
+ */
+struct pldm_get_file_table_resp {
+	uint8_t completion_code;       //!< Completion code
+	uint32_t next_transfer_handle; //!< Next data transfer handle
+	uint8_t transfer_flag;	       //!< Transfer flag
+	uint8_t table_data[1];	       //!< Table Data
+} __attribute__((packed));
+
+/** @struct pldm_file_attr_table_entry
+ *
+ * Structure representing File attribute table entry
+ */
+struct pldm_file_attr_table_entry {
+	uint32_t file_handle;		//!< File Handle
+	uint16_t file_name_length;	//!< File name length
+	uint8_t file_attr_table_nst[1]; //!< File name size traits
+} __attribute__((packed));
+
+/** @brief Decode GetFileTable command request data
+ *
+ *  @param[in] msg - Pointer to PLDM request message
+ *  @param[in] payload_length - Length of request payload
+ *  @param[out] trasnfer_handle - the handle of data
+ *  @param[out] transfer_opflag - Transfer operation flag
+ *  @param[out] table_type - the type of file table
+ *  @return pldm_completion_codes
+ */
+int decode_get_file_table_req(const struct pldm_msg *msg, size_t payload_length,
+			      uint32_t *transfer_handle,
+			      uint8_t *transfer_opflag, uint8_t *table_type);
+
+/** @brief Create a PLDM response for GetFileTable command
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in] next_transfer_handle - Handle to identify next portion of
+ *              data transfer
+ *  @param[in] transfer_flag - Represents the part of transfer
+ *  @param[in] table_data - pointer to file table data
+ *  @param[in] table_size - file table size
+ *  @param[in,out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param 'msg'
+ */
+int encode_get_file_table_resp(uint8_t instance_id, uint8_t completion_code,
+			       uint32_t next_transfer_handle,
+			       uint8_t transfer_flag, const uint8_t *table_data,
+			       size_t table_size, struct pldm_msg *msg);
+
+/** @brief Encode GetFileTable command request data
+ *
+ * @param[in] instance_id - Message's instance id
+ * @param[in] transfer_handle - the handle of data
+ * @param[in] transfer_opflag - Transfer operation flag
+ * @param[in] table_type - the type of file table
+ * @param[out] msg - Message will be written to this
+ * @return pldm_completion_codes
+ */
+int encode_get_file_table_req(uint8_t instance_id, uint32_t transfer_handle,
+			      uint8_t transfer_opflag, uint8_t table_type,
+			      struct pldm_msg *msg);
+
+/** @brief Decode GetFileTable command response data
+ * @param[in] msg - Response message
+ * @param[in] payload_length - length of response message payload
+ * @param[out] completion_code - PLDM completion code
+ * @param[out] next_transfer_handle -  Handle to identify next portion of data
+ * transfer
+ * @param[out] transfer_flag - Represents the part of transfer
+ * @param[out] file_table_data_start_offset - This data is a portion of the
+ * overall File Table
+ * @param[out] file_table_length - Length of the File table data
+ * @return pldm_completion_codes
+ */
+int decode_get_file_table_resp(const struct pldm_msg *msg,
+			       size_t payload_length, uint8_t *completion_code,
+			       uint32_t *next_transfer_handle,
+			       uint8_t *transfer_flag,
+			       uint8_t *file_table_data_start_offset,
+			       size_t *file_table_length);
+
+/** @struct pldm_read_file_req
+ *
+ *  Structure representing ReadFile request
+ */
+struct pldm_read_file_req {
+	uint32_t file_handle; //!< Handle to file
+	uint32_t offset;      //!< Offset to file where read starts
+	uint32_t length;      //!< Bytes to be read
+} __attribute__((packed));
+
+/** @struct pldm_read_file_resp
+ *
+ *  Structure representing ReadFile response data
+ */
+struct pldm_read_file_resp {
+	uint8_t completion_code; //!< Completion code
+	uint32_t length;	 //!< Number of bytes read
+	uint8_t file_data[1];	 //!< Address of this is where file data starts
+} __attribute__((packed));
+
+/** @struct pldm_write_file_req
+ *
+ *  Structure representing WriteFile request
+ */
+struct pldm_write_file_req {
+	uint32_t file_handle; //!< Handle to file
+	uint32_t offset;      //!< Offset to file where write starts
+	uint32_t length;      //!< Bytes to be written
+	uint8_t file_data[1]; //!< Address of this is where file data starts
+} __attribute__((packed));
+
+/** @struct pldm_write_file_resp
+ *
+ *  Structure representing WriteFile response data
+ */
+struct pldm_write_file_resp {
+	uint8_t completion_code; //!< Completion code
+	uint32_t length;	 //!< Bytes written
+} __attribute__((packed));
+
+/** @brief Decode Read File commands request
+ *
+ *  @param[in] msg - PLDM request message payload
+ *  @param[in] payload_length - Length of request payload
+ *  @param[out] file_handle - A handle to the file
+ *  @param[out] offset - Offset to the file at which the read should begin
+ *  @param[out] length - Number of bytes read
+ *  @return pldm_completion_codes
+ */
+int decode_read_file_req(const struct pldm_msg *msg, size_t payload_length,
+			 uint32_t *file_handle, uint32_t *offset,
+			 uint32_t *length);
+
+/** @brief Encode Read File commands request
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] file_handle - A handle to the file
+ *  @param[in] offset - Offset to the file at which the read should begin
+ *  @param[in] length - Number of bytes read
+ *  @param[in,out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param 'msg'
+ */
+int encode_read_file_req(uint8_t instance_id, uint32_t file_handle,
+			 uint32_t offset, uint32_t length,
+			 struct pldm_msg *msg);
+
+/** @brief Decode Read File commands response
+ *
+ *  @param[in] msg - PLDM response message payload
+ *  @param[in] payload_length - Length of request payload
+ *  @param[out] completion_code - PLDM completion code
+ *  @param[out] length - Number of bytes read. This could be less than what the
+ *                       requester asked for.
+ *  @param[out] file_data_offset - Offset where file data should be read in pldm
+ * msg.
+ *  @return pldm_completion_codes
+ */
+int decode_read_file_resp(const struct pldm_msg *msg, size_t payload_length,
+			  uint8_t *completion_code, uint32_t *length,
+			  size_t *file_data_offset);
+
+/** @brief Create a PLDM response for Read File
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in] length - Number of bytes read. This could be less than what the
+ *                      requester asked for.
+ *  @param[in,out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param 'msg'.
+ *  Although read file command response includes file data, this function
+ *  does not encode the file data to prevent additional copying of the data.
+ *  The position of file data is calculated by caller from address and size
+ *  of other input arguments.
+ */
+int encode_read_file_resp(uint8_t instance_id, uint8_t completion_code,
+			  uint32_t length, struct pldm_msg *msg);
+
+/** @brief Decode Write File commands request
+ *
+ *  @param[in] msg - PLDM request message payload
+ *  @param[in] payload_length - Length of request payload
+ *  @param[out] file_handle - A handle to the file
+ *  @param[out] offset - Offset to the file at which the write should begin
+ *  @param[out] length - Number of bytes to write
+ *  @param[out] file_data_offset - Offset where file data write begins in pldm
+ * msg.
+ *  @return pldm_completion_codes
+ */
+int decode_write_file_req(const struct pldm_msg *msg, size_t payload_length,
+			  uint32_t *file_handle, uint32_t *offset,
+			  uint32_t *length, size_t *file_data_offset);
+
+/** @brief Create a PLDM request for Write File
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] file_handle - A handle to the file
+ *  @param[in] offset - Offset to the file at which the read should begin
+ *  @param[in] length - Number of bytes written. This could be less than what
+ *                      the requester asked for.
+ *  @param[in,out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param 'msg'.
+ *  Although write file command request includes file data, this function
+ *  does not encode the file data to prevent additional copying of the data.
+ *  The position of file data is calculated by caller from address and size
+ *  of other input arguments.
+ */
+int encode_write_file_req(uint8_t instance_id, uint32_t file_handle,
+			  uint32_t offset, uint32_t length,
+			  struct pldm_msg *msg);
+
+/** @brief Decode Write File commands response
+ *
+ *  @param[in] msg - PLDM request message payload
+ *  @param[in] payload_length - Length of request payload
+ *  @param[out] completion_code - PLDM completion code
+ *  @param[out] length - Number of bytes written
+ *  @return pldm_completion_codes
+ */
+int decode_write_file_resp(const struct pldm_msg *msg, size_t payload_length,
+			   uint8_t *completion_code, uint32_t *length);
+
+/** @brief Create a PLDM response for Write File
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in] length - Number of bytes written. This could be less than what
+ *                      the requester asked for.
+ *  @param[in,out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param 'msg'
+ */
+int encode_write_file_resp(uint8_t instance_id, uint8_t completion_code,
+			   uint32_t length, struct pldm_msg *msg);
+
+/** @struct pldm_read_write_file_by_type_memory_req
+ *
+ *  Structure representing ReadFileByTypeIntoMemory and
+ * WriteFileByTypeFromMemory request
+ */
+struct pldm_read_write_file_by_type_memory_req {
+	uint16_t file_type;   //!< Type of file
+	uint32_t file_handle; //!< Handle to file
+	uint32_t offset;      //!< Offset to file where read starts
+	uint32_t length;      //!< Bytes to be read
+	uint64_t address;     //!< Memory address of the file
+} __attribute__((packed));
+
+/** @struct pldm_read_write_file_by_type_memory_resp
+ *
+ *  Structure representing ReadFileByTypeIntoMemory and
+ * WriteFileByTypeFromMemory response
+ */
+struct pldm_read_write_file_by_type_memory_resp {
+	uint8_t completion_code; //!< Completion code
+	uint32_t length;	 //!< Number of bytes read
+} __attribute__((packed));
+
+/** @brief Decode ReadFileByTypeIntoMemory and WriteFileByTypeFromMemory
+ * commands request data
+ *
+ *  @param[in] msg - Pointer to PLDM request message
+ *  @param[in] payload_length - Length of request payload
+ *  @param[in] file_type - Type of the file
+ *  @param[out] file_handle - A handle to the file
+ *  @param[out] offset - Offset to the file at which the read should begin
+ *  @param[out] length - Number of bytes to be read
+ *  @param[out] address - Memory address of the file content
+ *  @return pldm_completion_codes
+ */
+int decode_rw_file_by_type_memory_req(const struct pldm_msg *msg,
+				      size_t payload_length,
+				      uint16_t *file_type,
+				      uint32_t *file_handle, uint32_t *offset,
+				      uint32_t *length, uint64_t *address);
+
+/** @brief Create a PLDM response for ReadFileByTypeIntoMemory and
+ * WriteFileByTypeFromMemory
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] command - PLDM command
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in] length - Number of bytes read. This could be less than what the
+ *                      requester asked for.
+ *  @param[in,out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param 'msg'
+ */
+int encode_rw_file_by_type_memory_resp(uint8_t instance_id, uint8_t command,
+				       uint8_t completion_code, uint32_t length,
+				       struct pldm_msg *msg);
+
+/** @brief Encode ReadFileByTypeIntoMemory and WriteFileByTypeFromMemory
+ *         commands request data
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] command - PLDM command
+ *  @param[in] file_type - Type of the file
+ *  @param[in] file_handle - A handle to the file
+ *  @param[in] offset -  Offset to the file at which the read should begin
+ *  @param[in] length -  Number of bytes to be read/written
+ *  @param[in] address - Memory address where the file content has to be
+ *                       written to
+ *  @param[out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ */
+int encode_rw_file_by_type_memory_req(uint8_t instance_id, uint8_t command,
+				      uint16_t file_type, uint32_t file_handle,
+				      uint32_t offset, uint32_t length,
+				      uint64_t address, struct pldm_msg *msg);
+
+/** @brief Decode ReadFileTypeIntoMemory and WriteFileTypeFromMemory
+ *         commands response data
+ *
+ *  @param[in] msg - pointer to PLDM response message
+ *  @param[in] payload_length - Length of response payload
+ *  @param[out] completion_code - PLDM completion code
+ *  @param[out] length - Number of bytes to be read/written
+ *  @return pldm_completion_codes
+ */
+int decode_rw_file_by_type_memory_resp(const struct pldm_msg *msg,
+				       size_t payload_length,
+				       uint8_t *completion_code,
+				       uint32_t *length);
+
+/** @struct pldm_new_file_req
+ *
+ *  Structure representing NewFile request
+ */
+struct pldm_new_file_req {
+	uint16_t file_type;   //!< Type of file
+	uint32_t file_handle; //!< Handle to file
+	uint64_t length;      //!< Number of bytes in new file
+} __attribute__((packed));
+
+/** @struct pldm_new_file_resp
+ *
+ *  Structure representing NewFile response data
+ */
+struct pldm_new_file_resp {
+	uint8_t completion_code; //!< Completion code
+} __attribute__((packed));
+
+/** @brief Decode NewFileAvailable command request data
+ *
+ *  @param[in] msg - Pointer to PLDM request message
+ *  @param[in] payload_length - Length of request payload
+ *  @param[in] file_type - Type of the file
+ *  @param[out] file_handle - A handle to the file
+ *  @param[out] length - Number of bytes in new file
+ *  @return pldm_completion_codes
+ */
+int decode_new_file_req(const struct pldm_msg *msg, size_t payload_length,
+			uint16_t *file_type, uint32_t *file_handle,
+			uint64_t *length);
+
+/** @brief Create a PLDM response for NewFileAvailable
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in,out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param 'msg'
+ */
+int encode_new_file_resp(uint8_t instance_id, uint8_t completion_code,
+			 struct pldm_msg *msg);
+
+/** @brief Encode NewFileAvailable command request data
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] file_type - Type of the file
+ *  @param[in] file_handle - A handle to the file
+ *  @param[in] length -  Number of bytes in new file
+ *  @param[out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ */
+int encode_new_file_req(uint8_t instance_id, uint16_t file_type,
+			uint32_t file_handle, uint64_t length,
+			struct pldm_msg *msg);
+
+/** @brief Decode NewFileAvailable command response data
+ *
+ *  @param[in] msg - pointer to PLDM response message
+ *  @param[in] payload_length - Length of response payload
+ *  @param[out] completion_code - PLDM completion code
+ *  @return pldm_completion_codes
+ */
+int decode_new_file_resp(const struct pldm_msg *msg, size_t payload_length,
+			 uint8_t *completion_code);
+
+/** @struct pldm_read_write_file_by_type_req
+ *
+ *  Structure representing ReadFileByType and
+ *  WriteFileByType request
+ */
+struct pldm_read_write_file_by_type_req {
+	uint16_t file_type;   //!< Type of file
+	uint32_t file_handle; //!< Handle to file
+	uint32_t offset;      //!< Offset to file where read/write starts
+	uint32_t length;      //!< Bytes to be read
+} __attribute__((packed));
+
+/** @struct pldm_read_write_file_by_type_resp
+ *
+ *  Structure representing ReadFileByType and
+ *  WriteFileByType response
+ */
+struct pldm_read_write_file_by_type_resp {
+	uint8_t completion_code; //!< Completion code
+	uint32_t length;	 //!< Number of bytes read
+} __attribute__((packed));
+
+/** @brief Decode ReadFileByType and WriteFileByType
+ *  commands request data
+ *
+ *  @param[in] msg - Pointer to PLDM request message
+ *  @param[in] payload_length - Length of request payload
+ *  @param[out] file_type - Type of the file
+ *  @param[out] file_handle - A handle to the file
+ *  @param[out] offset - Offset to the file at which the read/write should begin
+ *  @param[out] length - Number of bytes to be read/written
+ *  @return pldm_completion_codes
+ */
+int decode_rw_file_by_type_req(const struct pldm_msg *msg,
+			       size_t payload_length, uint16_t *file_type,
+			       uint32_t *file_handle, uint32_t *offset,
+			       uint32_t *length);
+
+/** @brief Create a PLDM response for ReadFileByType and
+ *  WriteFileByType
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] command - PLDM command
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in] length - Number of bytes read/written. This could be less than
+ *                      what the requester asked for.
+ *  @param[in,out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param 'msg'
+ *  @note File content has to be copied directly by the caller.
+ */
+int encode_rw_file_by_type_resp(uint8_t instance_id, uint8_t command,
+				uint8_t completion_code, uint32_t length,
+				struct pldm_msg *msg);
+
+/** @brief Encode ReadFileByType and WriteFileByType
+ *         commands request data
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] command - PLDM command
+ *  @param[in] file_type - Type of the file
+ *  @param[in] file_handle - A handle to the file
+ *  @param[in] offset -  Offset to the file at which the read should begin
+ *  @param[in] length -  Number of bytes to be read/written
+ *  @param[out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note File content has to be read directly by the caller.
+ */
+int encode_rw_file_by_type_req(uint8_t instance_id, uint8_t command,
+			       uint16_t file_type, uint32_t file_handle,
+			       uint32_t offset, uint32_t length,
+			       struct pldm_msg *msg);
+
+/** @brief Decode ReadFileByType and WriteFileByType
+ *         commands response data
+ *
+ *  @param[in] msg - pointer to PLDM response message
+ *  @param[in] payload_length - Length of response payload
+ *  @param[out] completion_code - PLDM completion code
+ *  @param[out] length - Number of bytes to be read/written
+ *  @return pldm_completion_codes
+ */
+int decode_rw_file_by_type_resp(const struct pldm_msg *msg,
+				size_t payload_length, uint8_t *completion_code,
+				uint32_t *length);
+
+/** @struct pldm_file_ack_req
+ *
+ *  Structure representing FileAck request
+ */
+struct pldm_file_ack_req {
+	uint16_t file_type;   //!< Type of file
+	uint32_t file_handle; //!< Handle to file
+	uint8_t file_status;  //!< Status of file processing
+} __attribute__((packed));
+
+/** @struct pldm_file_ack_resp
+ *
+ *  Structure representing NewFile response data
+ */
+struct pldm_file_ack_resp {
+	uint8_t completion_code; //!< Completion code
+} __attribute__((packed));
+
+/** @brief Decode FileAck command request data
+ *
+ *  @param[in] msg - Pointer to PLDM request message
+ *  @param[in] payload_length - Length of request payload
+ *  @param[out] file_type - Type of the file
+ *  @param[out] file_handle - A handle to the file
+ *  @param[out] file_status - Status of file processing
+ *  @return pldm_completion_codes
+ */
+int decode_file_ack_req(const struct pldm_msg *msg, size_t payload_length,
+			uint16_t *file_type, uint32_t *file_handle,
+			uint8_t *file_status);
+
+/** @brief Create a PLDM response for FileAck
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in,out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param 'msg'
+ */
+int encode_file_ack_resp(uint8_t instance_id, uint8_t completion_code,
+			 struct pldm_msg *msg);
+
+/** @brief Encode FileAck command request data
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] file_type - Type of the file
+ *  @param[in] file_handle - A handle to the file
+ *  @param[in] file_status - Status of file processing
+ *  @param[out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ */
+int encode_file_ack_req(uint8_t instance_id, uint16_t file_type,
+			uint32_t file_handle, uint8_t file_status,
+			struct pldm_msg *msg);
+
+/** @brief Decode FileAck command response data
+ *
+ *  @param[in] msg - pointer to PLDM response message
+ *  @param[in] payload_length - Length of response payload
+ *  @param[out] completion_code - PLDM completion code
+ *  @return pldm_completion_codes
+ */
+int decode_file_ack_resp(const struct pldm_msg *msg, size_t payload_length,
+			 uint8_t *completion_code);
+
+/* FileAckWithMetadata */
+
+/** @struct pldm_file_ack_with_meta_data_req
+ *
+ *  Structure representing FileAckWithMetadata request
+ */
+struct pldm_file_ack_with_meta_data_req {
+	uint16_t file_type;	   //!< Type of file
+	uint32_t file_handle;	   //!< Handle to file
+	uint8_t file_status;	   //!< Status of file processing
+	uint32_t file_meta_data_1; //!< Meta data specific to file type 1
+	uint32_t file_meta_data_2; //!< Meta data specific to file type 2
+	uint32_t file_meta_data_3; //!< Meta data specific to file type 3
+	uint32_t file_meta_data_4; //!< meta data specific to file type 4
+} __attribute__((packed));
+
+/** @struct pldm_file_ack_with_meta_data_resp
+ *
+ *  Structure representing FileAckWithMetadata response
+ */
+struct pldm_file_ack_with_meta_data_resp {
+	uint8_t completion_code; //!< Completion code
+} __attribute__((packed));
+
+/** @brief Encode FileAckWithMetadata request data
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] file_type - Type of the file
+ *  @param[in] file_handle - A handle to the file
+ *  @param[in] file_status - Status of file processing
+ *  @param[in] file_meta_data_1 - meta data specific to file type 1
+ *  @param[in] file_meta_data_2 - meta data specific to file type 2
+ *  @param[in] file_meta_data_3 - meta data specific to file type 3
+ *  @param[in] file_meta_data_4 - Meta data specific to file type 4
+ *  @param[out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ */
+int encode_file_ack_with_meta_data_req(
+    uint8_t instance_id, uint16_t file_type, uint32_t file_handle,
+    uint8_t file_status, uint32_t file_meta_data_1, uint32_t file_meta_data_2,
+    uint32_t file_meta_data_3, uint32_t file_meta_data_4, struct pldm_msg *msg);
+
+/** @brief Decode FileAckWithMetadata command response data
+ *
+ * @param[in] msg - pointer to PLDM response message
+ * @param[in] payload_length - Length of response payload
+ * @param[out] completion_code - PLDM completion code
+ * @return pldm_completion_codes
+ */
+int decode_file_ack_with_meta_data_resp(const struct pldm_msg *msg,
+					size_t payload_length,
+					uint8_t *completion_code);
+
+/** @brief Decode FileAckWithMetadata request data
+ *
+ * @param[in] msg - Pointer to PLDM request message
+ * @param[in] payload_length - Length of request payload
+ * @param[out] file_type - Type of the file
+ * @param[out] file_handle - A handle to the file
+ * @param[out] file_status - Status of file processing
+ * @param[out] file_meta_data_1 - meta data specific to file type 1
+ * @param[out] file_meta_data_2 - meta data specific to file type 2
+ * @param[out] file_meta_data_3 - meta data specific to file type 3
+ * @param[out] file_meta_data_4 - Meta data specific to file type 4
+ * @return pldm_completion_codes
+ */
+int decode_file_ack_with_meta_data_req(
+    const struct pldm_msg *msg, size_t payload_length, uint16_t *file_type,
+    uint32_t *file_handle, uint8_t *file_status, uint32_t *file_meta_data_1,
+    uint32_t *file_meta_data_2, uint32_t *file_meta_data_3,
+    uint32_t *file_meta_data_4);
+
+/** @brief Create a PLDM response message for FileAckWithMetadata
+ *
+ * @param[in] instance_id - Message's instance id
+ * @param[in] completion_code - PLDM completion code
+ * @param[in,out] msg - Message will be written to this
+ * @return pldm_completion_codes
+ */
+int encode_file_ack_with_meta_data_resp(uint8_t instance_id,
+					uint8_t completion_code,
+					struct pldm_msg *msg);
+
+/* NewFileAvailableWithMetaData */
+
+/** @struct pldm_new_file_with_metadata_req
+ *
+ *  Structure representing NewFileAvailableWithMetaData request
+ */
+
+struct pldm_new_file_with_metadata_req {
+	uint16_t file_type;	   //!< Type of file
+	uint32_t file_handle;	   //!< Handle to file
+	uint64_t length;	   //!< Number of bytes in new file
+	uint32_t file_meta_data_1; //!< Meta data specific to file type 1
+	uint32_t file_meta_data_2; //!< Meta data specific to file type 2
+	uint32_t file_meta_data_3; //!< Meta data specific to file type 3
+	uint32_t file_meta_data_4; //!< Meta data specific to file type 4
+} __attribute__((packed));
+
+/** @struct pldm_new_file_with_metadata_resp
+ *
+ *  Structure representing NewFileAvailableWithMetaData response data
+ */
+struct pldm_new_file_with_metadata_resp {
+	uint8_t completion_code; //!< Completion code
+} __attribute__((packed));
+
+/** @brief Encode NewFileAvailableWithMetaData request data
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] file_type - Type of the file
+ *  @param[in] file_handle - A handle to the file
+ *  @param[in] length -  Number of bytes in new file
+ *  @param[in] file_meta_data_1 - Meta data specific to file type 1
+ *  @param[in] file_meta_data_2 - Meta data specific to file type 2
+ *  @param[in] file_meta_data_3 - Meta data specific to file type 3
+ *  @param[in] file_meta_data_4 - Meta data specific to file type 4
+ *  @param[out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ */
+int encode_new_file_with_metadata_req(
+    uint8_t instance_id, uint16_t file_type, uint32_t file_handle,
+    uint64_t length, uint32_t file_meta_data_1, uint32_t file_meta_data_2,
+    uint32_t file_meta_data_3, uint32_t file_meta_data_4, struct pldm_msg *msg);
+
+/** @brief Decode NewFileAvailableWithMetaData response data
+ *
+ *  @param[in] msg - pointer to PLDM response message
+ *  @param[in] payload_length - Length of response payload
+ *  @param[out] completion_code - PLDM completion code
+ *  @return pldm_completion_codes
+ */
+int decode_new_file_with_metadata_resp(const struct pldm_msg *msg,
+				       size_t payload_length,
+				       uint8_t *completion_code);
+
+/** @brief Decode NewFileAvailableWithMetaData request data
+ *
+ *  @param[in] msg - Pointer to PLDM request message
+ *  @param[in] payload_length - Length of request payload
+ *  @param[out] file_type - Type of the file
+ *  @param[out] file_handle - A handle to the file
+ *  @param[out] length - Number of bytes in new file
+ *  @param[out] file_meta_data_1 - Meta data specific to file type 1
+ *  @param[out] file_meta_data_2 - Meta data specific to file type 2
+ *  @param[out] file_meta_data_3 - Meta data specific to file type 3
+ *  @param[out] file_meta_data_4 - Meta data specific to file type 4
+ *  @return pldm_completion_codes
+ */
+int decode_new_file_with_metadata_req(
+    const struct pldm_msg *msg, size_t payload_length, uint16_t *file_type,
+    uint32_t *file_handle, uint64_t *length, uint32_t *file_meta_data_1,
+    uint32_t *file_meta_data_2, uint32_t *file_meta_data_3,
+    uint32_t *file_meta_data_4);
+
+/** @brief Create a PLDM response for NewFileAvailableWithMetaData
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in,out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param 'msg'
+ */
+int encode_new_file_with_metadata_resp(uint8_t instance_id,
+				       uint8_t completion_code,
+				       struct pldm_msg *msg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FILEIO_H */
diff --git a/include/libpldm/oem/ibm/libpldm/fru_oem_ibm.h b/include/libpldm/oem/ibm/libpldm/fru_oem_ibm.h
new file mode 100644
index 0000000..c97f8b0
--- /dev/null
+++ b/include/libpldm/oem/ibm/libpldm/fru_oem_ibm.h
@@ -0,0 +1,21 @@
+#ifndef OEM_IBM_FRU_H
+#define OEM_IBM_FRU_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+enum pldm_oem_ibm_fru_field_type {
+	PLDM_OEM_FRU_FIELD_TYPE_IANA = 0X01,
+	PLDM_OEM_FRU_FIELD_TYPE_RT = 0X02,
+	PLDM_OEM_FRU_FIELD_TYPE_LOCATION_CODE = 0XFE,
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OEM_IBM_FRU_H */
diff --git a/include/libpldm/oem/ibm/libpldm/host.h b/include/libpldm/oem/ibm/libpldm/host.h
new file mode 100644
index 0000000..ed121ae
--- /dev/null
+++ b/include/libpldm/oem/ibm/libpldm/host.h
@@ -0,0 +1,108 @@
+#ifndef OEM_IBM_HOST_H
+#define OEM_IBM_HOST_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base.h"
+
+/* Maximum size for request */
+#define PLDM_GET_ALERT_STATUS_REQ_BYTES 1
+
+/* Response lengths are inclusive of completion code */
+#define PLDM_GET_ALERT_STATUS_RESP_BYTES 9
+
+enum pldm_host_commands {
+	PLDM_HOST_GET_ALERT_STATUS = 0xF0 // Custom oem cmd
+};
+
+/** @brief PLDM Command specific codes
+ */
+enum pldm_host_completion_codes { PLDM_HOST_UNSUPPORTED_FORMAT_VERSION = 0x81 };
+
+/** @struct pldm_get_alert_states_resp
+ *
+ * Structure representing GetAlertStatus response packet
+ */
+struct pldm_get_alert_status_resp {
+	uint8_t completion_code;
+	uint32_t rack_entry;
+	uint32_t pri_cec_node;
+} __attribute__((packed));
+
+/* Requester */
+
+/* GetAlertStatus */
+
+/** @brief Create a PLDM request message for GetAlertStatus
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] version_id - The command/response format. 0x00 for this format
+ *  @param[out] msg - Message will be written to this
+ *  @param[in] payload_length - Length of request message payload
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_get_alert_status_req(uint8_t instance_id, uint8_t version_id,
+				struct pldm_msg *msg, size_t payload_length);
+
+/** @brief Decode GetAlertStatus response data
+ *
+ *  Note:
+ *  * If the return value is not PLDM_SUCCESS, it represents a
+ * transport layer error.
+ *  * If the completion_code value is not PLDM_SUCCESS, it represents a
+ * protocol layer error and all the out-parameters are invalid.
+ *
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - Length of request message payload
+ *  @param[out] completion_code - PLDM completion code
+ *  @param[out] rack_entry - Enclosure ID, Alert Status, Flags, Config ID
+ *  @param[out] pri_cec_node - Enclosure ID, Alert Status, Flags, Config ID
+ *  @return pldm_completion_codes
+ */
+int decode_get_alert_status_resp(const struct pldm_msg *msg,
+				 size_t payload_length,
+				 uint8_t *completion_code, uint32_t *rack_entry,
+				 uint32_t *pri_cec_node);
+
+/* Responder */
+
+/* GetAlertStatus */
+
+/** @brief Decode GetAlertStatus request data
+ *
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - Length of request message payload
+ *  @param[out] version_id - the command/response format. 0x00 for this format
+ *  @return pldm_completion_codes
+ */
+int decode_get_alert_status_req(const struct pldm_msg *msg,
+				size_t payload_length, uint8_t *version_id);
+
+/** @brief Create a PLDM OEM response message for GetAlertStatus
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in] rack_entry - Enclosure ID, Alert Status, Flags, Config ID
+ *  @param[in] pri_cec_node - Enclosure ID, Alert Status, Flags, Config ID
+ *  @param[out] msg - Message will be written to this
+ *  @param[in] payload_length - Length of request message payload
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.body.payload'
+ */
+int encode_get_alert_status_resp(uint8_t instance_id, uint8_t completion_code,
+				 uint32_t rack_entry, uint32_t pri_cec_node,
+				 struct pldm_msg *msg, size_t payload_length);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OEM_IBM_HOST_H */
diff --git a/include/libpldm/oem/ibm/libpldm/platform_oem_ibm.h b/include/libpldm/oem/ibm/libpldm/platform_oem_ibm.h
new file mode 100644
index 0000000..f0aafd3
--- /dev/null
+++ b/include/libpldm/oem/ibm/libpldm/platform_oem_ibm.h
@@ -0,0 +1,56 @@
+#ifndef PLATFORM_OEM_IBM_H
+#define PLATFORM_OEM_IBM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "base.h"
+#include <stddef.h>
+#include <stdint.h>
+
+enum pldm_event_types_ibm_oem {
+	PLDM_EVENT_TYPE_OEM_EVENT_BIOS_ATTRIBUTE_UPDATE = 0xF0,
+};
+
+/** @struct pldm_bios_attribute_update_event_req
+ *
+ * 	Structure representing PlatformEventMessage command request data for OEM
+ *  event type BIOS attribute update.
+ */
+struct pldm_bios_attribute_update_event_req {
+	uint8_t format_version;
+	uint8_t tid;
+	uint8_t event_class;
+	uint8_t num_handles;
+	uint8_t bios_attribute_handles[1];
+} __attribute__((packed));
+
+/** @brief Encode PlatformEventMessage request data for BIOS attribute update
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] format_version - Version of the event format
+ *  @param[in] tid - Terminus ID for the terminus that originated the event
+ *                   message
+ *  @param[in] num_handles - Number of BIOS handles with an update
+ *  @param[in] list_of_handles - Pointer to the list of BIOS attribute handles
+ *  @param[in] payload_length - Length of request message payload
+ *  @param[out] msg - Message will be written to this
+ *
+ *  @return pldm_completion_codes
+ *
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_bios_attribute_update_event_req(uint8_t instance_id,
+					   uint8_t format_version, uint8_t tid,
+					   uint8_t num_handles,
+					   const uint8_t *list_of_handles,
+					   size_t payload_length,
+					   struct pldm_msg *msg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PLATFORM_OEM_IBM_H */
\ No newline at end of file
diff --git a/include/libpldm/oem/ibm/libpldm/state_set_oem_ibm.h b/include/libpldm/oem/ibm/libpldm/state_set_oem_ibm.h
new file mode 100644
index 0000000..5c8378b
--- /dev/null
+++ b/include/libpldm/oem/ibm/libpldm/state_set_oem_ibm.h
@@ -0,0 +1,58 @@
+#ifndef STATE_SET_OEM_IBM_H
+#define STATE_SET_OEM_IBM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief IBM OEM State Set IDs */
+enum ibm_oem_pldm_state_set_ids {
+	PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE = 32768,
+	PLDM_OEM_IBM_BOOT_STATE = 32769,
+	PLDM_OEM_IBM_VERIFICATION_STATE = 32770,
+	PLDM_OEM_IBM_SYSTEM_POWER_STATE = 32771,
+	PLDM_OEM_IBM_SBE_MAINTENANCE_STATE = 32772,
+	PLDM_OEM_IBM_SBE_HRESET_STATE = 32776,
+};
+
+enum ibm_oem_pldm_state_set_firmware_update_state_values {
+	START = 0x1,
+	END = 0x2,
+	FAIL = 0x3,
+	ABORT = 0x4,
+	ACCEPT = 0x5,
+	REJECT = 0x6,
+};
+
+enum ibm_oem_pldm_state_set_boot_state_values {
+	P = 0x1,
+	T = 0x2,
+};
+
+enum ibm_oem_pldm_state_set_verification_state_values {
+	VALID = 0x0,
+	ENTITLEMENT_FAIL = 0x1,
+	BANNED_PLATFORM_FAIL = 0x2,
+	MIN_MIF_FAIL = 0x4,
+};
+
+enum ibm_oem_pldm_state_set_system_power_state_values {
+	POWER_CYCLE_HARD = 0x1
+};
+
+enum ibm_oem_pldm_state_set_sbe_dump_state_values {
+	SBE_DUMP_COMPLETED = 0x1,
+	SBE_RETRY_REQUIRED = 0x2,
+};
+
+enum ibm_oem_pldm_state_set_sbe_hreset_state_values {
+	SBE_HRESET_NOT_READY = 0x1,
+	SBE_HRESET_READY = 0x2,
+	SBE_HRESET_FAILED = 0x3,
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STATE_SET_OEM_IBM_H */
diff --git a/include/libpldm/pdr.h b/include/libpldm/pdr.h
new file mode 100644
index 0000000..671b726
--- /dev/null
+++ b/include/libpldm/pdr.h
@@ -0,0 +1,410 @@
+#ifndef PDR_H
+#define PDR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+/** @struct pldm_pdr
+ *  opaque structure that acts as a handle to a PDR repository
+ */
+typedef struct pldm_pdr pldm_pdr;
+
+/** @struct pldm_pdr_record
+ *  opaque structure that acts as a handle to a PDR record
+ */
+typedef struct pldm_pdr_record pldm_pdr_record;
+
+/* ====================== */
+/* Common PDR access APIs */
+/* ====================== */
+
+/** @brief Make a new PDR repository
+ *
+ *  @return opaque pointer that acts as a handle to the repository; NULL if no
+ *  repository could be created
+ *
+ *  @note  Caller may make multiple repositories (for its own PDRs, as well as
+ *  for PDRs received by other entities) and can associate the returned handle
+ *  to a PLDM terminus id.
+ */
+pldm_pdr *pldm_pdr_init();
+
+/** @brief Destroy a PDR repository (and free up associated resources)
+ *
+ *  @param[in/out] repo - pointer to opaque pointer acting as a PDR repo handle
+ */
+void pldm_pdr_destroy(pldm_pdr *repo);
+
+/** @brief Get number of records in a PDR repository
+ *
+ *  @param[in] repo - opaque pointer acting as a PDR repo handle
+ *
+ *  @return uint32_t - number of records
+ */
+uint32_t pldm_pdr_get_record_count(const pldm_pdr *repo);
+
+/** @brief Get size of a PDR repository, in bytes
+ *
+ *  @param[in] repo - opaque pointer acting as a PDR repo handle
+ *
+ *  @return uint32_t - size in bytes
+ */
+uint32_t pldm_pdr_get_repo_size(const pldm_pdr *repo);
+
+/** @brief Add a PDR record to a PDR repository
+ *
+ *  @param[in/out] repo - opaque pointer acting as a PDR repo handle
+ *  @param[in] data - pointer to a PDR record, pointing to a PDR definition as
+ *  per DSP0248. This data is memcpy'd.
+ *  @param[in] size - size of input PDR record in bytes
+ *  @param[in] record_handle - record handle of input PDR record; if this is set
+ *  to 0, then a record handle is computed and assigned to this PDR record
+ *  @param[in] is_remote - if true, then the PDR is not from this terminus
+ *  @param[in] terminus_handle - terminus handle of the input PDR record
+ *
+ *  @return uint32_t - record handle assigned to PDR record
+ */
+uint32_t pldm_pdr_add(pldm_pdr *repo, const uint8_t *data, uint32_t size,
+		      uint32_t record_handle, bool is_remote,
+		      uint16_t terminus_handle);
+
+/** @brief Get record handle of a PDR record
+ *
+ *  @param[in] repo - opaque pointer acting as a PDR repo handle
+ *  @param[in] record - opaque pointer acting as a PDR record handle
+ *
+ *  @return uint32_t - record handle assigned to PDR record; 0 if record is not
+ *  found
+ */
+uint32_t pldm_pdr_get_record_handle(const pldm_pdr *repo,
+				    const pldm_pdr_record *record);
+
+/** @brief Find PDR record by record handle
+ *
+ *  @param[in] repo - opaque pointer acting as a PDR repo handle
+ *  @param[in] record_handle - input record handle
+ *  @param[in/out] data - will point to PDR record data (as per DSP0248) on
+ *                        return
+ *  @param[out] size - *size will be size of PDR record
+ *  @param[out] next_record_handle - *next_record_handle will be the record
+ *  handle of record next to the returned PDR record
+ *
+ *  @return opaque pointer acting as PDR record handle, will be NULL if record
+ *  was not found
+ */
+const pldm_pdr_record *pldm_pdr_find_record(const pldm_pdr *repo,
+					    uint32_t record_handle,
+					    uint8_t **data, uint32_t *size,
+					    uint32_t *next_record_handle);
+
+/** @brief Get PDR record next to input PDR record
+ *
+ *  @param[in] repo - opaque pointer acting as a PDR repo handle
+ *  @param[in] curr_record - opaque pointer acting as a PDR record handle
+ *  @param[in/out] data - will point to PDR record data (as per DSP0248) on
+ *                        return
+ *  @param[out] size - *size will be size of PDR record
+ *  @param[out] next_record_handle - *next_record_handle will be the record
+ *  handle of record nect to the returned PDR record
+ *
+ *  @return opaque pointer acting as PDR record handle, will be NULL if record
+ *  was not found
+ */
+const pldm_pdr_record *
+pldm_pdr_get_next_record(const pldm_pdr *repo,
+			 const pldm_pdr_record *curr_record, uint8_t **data,
+			 uint32_t *size, uint32_t *next_record_handle);
+
+/** @brief Find (first) PDR record by PDR type
+ *
+ *  @param[in] repo - opaque pointer acting as a PDR repo handle
+ *  @param[in] pdr_type - PDR type number as per DSP0248
+ *  @param[in] curr_record - opaque pointer acting as a PDR record handle; if
+ *  not NULL, then search will begin from this record's next record
+ *  @param[in/out] data - will point to PDR record data (as per DSP0248) on
+ *                        return, if input is not NULL
+ *  @param[out] size - *size will be size of PDR record, if input is not NULL
+ *
+ *  @return opaque pointer acting as PDR record handle, will be NULL if record
+ *  was not found
+ */
+const pldm_pdr_record *
+pldm_pdr_find_record_by_type(const pldm_pdr *repo, uint8_t pdr_type,
+			     const pldm_pdr_record *curr_record, uint8_t **data,
+			     uint32_t *size);
+
+bool pldm_pdr_record_is_remote(const pldm_pdr_record *record);
+
+/** @brief Remove all PDR records that belong to a remote terminus
+ *
+ *  @param[in] repo - opaque pointer acting as a PDR repo handle
+ */
+void pldm_pdr_remove_remote_pdrs(pldm_pdr *repo);
+
+/** @brief Remove all remote PDR's that beling to a specific terminus
+ *         handle
+ *  @param[in] repo - opaque pointer acting as a PDR repo handle
+ *  @param[in] terminus_handle - Terminus Handle of the remove PLDM terminus
+ */
+void pldm_pdr_remove_pdrs_by_terminus_handle(pldm_pdr *repo,
+					     uint16_t terminus_handle);
+
+/** @brief Update the validity of TL PDR - the validity is decided based on
+ * whether the valid bit is set or not as per the spec DSP0248
+ *
+ * @param[in] repo - opaque pointer acting as a PDR repo handle
+ * @param[in] terminusHandle - PLDM terminus handle
+ * @param[in] tid - Terminus ID
+ * @param[in] tlEid - MCTP endpoint EID
+ * @param[in] valid - validity bit of TLPDR
+ */
+void pldm_pdr_update_TL_pdr(const pldm_pdr *repo, uint16_t terminusHandle,
+			    uint8_t tid, uint8_t tlEid, bool valid);
+
+/* ======================= */
+/* FRU Record Set PDR APIs */
+/* ======================= */
+
+/** @brief Add a FRU record set PDR record to a PDR repository
+ *
+ *  @param[in/out] repo - opaque pointer acting as a PDR repo handle
+ *  @param[in] terminus_handle - PLDM terminus handle of terminus owning the PDR
+ *  record
+ *  @param[in] fru_rsi - FRU record set identifier
+ *  @param[in] entity_type - entity type of FRU
+ *  @param[in] entity_instance_num - entity instance number of FRU
+ *  @param[in] container_id - container id of FRU
+ *  @param[in] bmc_record_handle - handle used to construct the next record
+ *
+ *  @return uint32_t - record handle assigned to PDR record
+ */
+uint32_t pldm_pdr_add_fru_record_set(pldm_pdr *repo, uint16_t terminus_handle,
+				     uint16_t fru_rsi, uint16_t entity_type,
+				     uint16_t entity_instance_num,
+				     uint16_t container_id,
+				     uint32_t bmc_record_handle);
+
+/** @brief Find a FRU record set PDR by FRU record set identifier
+ *
+ *  @param[in] repo - opaque pointer acting as a PDR repo handle
+ *  @param[in] fru_rsi - FRU record set identifier
+ *  @param[in] terminus_handle - *terminus_handle will be FRU terminus handle of
+ *  found PDR, or 0 if not found
+ *  @param[in] entity_type - *entity_type will be FRU entity type of found PDR,
+ *  or 0 if not found
+ *  @param[in] entity_instance_num - *entity_instance_num will be FRU entity
+ *  instance number of found PDR, or 0 if not found
+ *  @param[in] container_id - *cintainer_id will be FRU container id of found
+ *  PDR, or 0 if not found
+ *
+ *  @return uint32_t - record handle assigned to PDR record
+ */
+const pldm_pdr_record *pldm_pdr_fru_record_set_find_by_rsi(
+    const pldm_pdr *repo, uint16_t fru_rsi, uint16_t *terminus_handle,
+    uint16_t *entity_type, uint16_t *entity_instance_num,
+    uint16_t *container_id);
+
+/* =========================== */
+/* Entity Association PDR APIs */
+/* =========================== */
+
+typedef struct pldm_entity {
+	uint16_t entity_type;
+	uint16_t entity_instance_num;
+	uint16_t entity_container_id;
+} __attribute__((packed)) pldm_entity;
+
+enum entity_association_containment_type {
+	PLDM_ENTITY_ASSOCIAION_PHYSICAL = 0x0,
+	PLDM_ENTITY_ASSOCIAION_LOGICAL = 0x1,
+};
+
+/** @struct pldm_entity_association_tree
+ *  opaque structure that represents the entity association hierarchy
+ */
+typedef struct pldm_entity_association_tree pldm_entity_association_tree;
+
+/** @struct pldm_entity_node
+ *  opaque structure that represents a node in the entity association hierarchy
+ */
+typedef struct pldm_entity_node pldm_entity_node;
+
+/** @brief Make a new entity association tree
+ *
+ *  @return opaque pointer that acts as a handle to the tree; NULL if no
+ *  tree could be created
+ */
+pldm_entity_association_tree *pldm_entity_association_tree_init();
+
+/** @brief Add an entity into the entity association tree
+ *
+ *  @param[in/out] tree - opaque pointer acting as a handle to the tree
+ *  @param[in/out] entity - pointer to the entity to be added. Input has the
+ *                          entity type. On output, instance number and the
+ *                          container id are populated.
+ *  @param[in] entity_instance_number - entity instance number, we can use the
+ *                                      entity instance number of the entity by
+ *                                      default if its value is equal 0xFFFF.
+ *  @param[in] parent - pointer to the node that should be the parent of input
+ *                      entity. If this is NULL, then the entity is the root
+ *  @param[in] association_type - relation with the parent : logical or physical
+ *
+ *  @return pldm_entity_node* - opaque pointer to added entity
+ */
+pldm_entity_node *pldm_entity_association_tree_add(
+    pldm_entity_association_tree *tree, pldm_entity *entity,
+    uint16_t entity_instance_number, pldm_entity_node *parent,
+    uint8_t association_type);
+
+/** @brief Visit and note each entity in the entity association tree
+ *
+ *  @param[in] tree - opaque pointer acting as a handle to the tree
+ *  @param[out] entities - pointer to list of pldm_entity's. To be free()'d by
+ *                         the caller
+ *  @param[out] size - number of pldm_entity's
+ */
+void pldm_entity_association_tree_visit(pldm_entity_association_tree *tree,
+					pldm_entity **entities, size_t *size);
+
+/** @brief Extract pldm entity by the pldm_entity_node
+ *
+ *  @param[in] node     - opaque pointer to added entity
+ *
+ *  @return pldm_entity - pldm entity
+ */
+pldm_entity pldm_entity_extract(pldm_entity_node *node);
+
+/** @brief Destroy entity association tree
+ *
+ *  @param[in] tree - opaque pointer acting as a handle to the tree
+ */
+void pldm_entity_association_tree_destroy(pldm_entity_association_tree *tree);
+
+/** @brief Check if input enity node is a parent
+ *
+ *  @param[in] node - opaque pointer acting as a handle to an entity node
+ *
+ *  @return bool true if node is a parent, false otherwise
+ */
+bool pldm_entity_is_node_parent(pldm_entity_node *node);
+
+/** @brief Get parent of entity
+ *
+ *  @param[in] node - opaque pointer acting as a handle to an entity node
+ *
+ *  @return pldm_entity - pldm entity
+ */
+pldm_entity pldm_entity_get_parent(pldm_entity_node *node);
+
+/** @brief Check the current pldm entity is exist parent
+ *
+ *  @param[in] node - opaque pointer acting as a handle to an entity node
+ *
+ *  @return bool true if exist parent, false otherwise
+ */
+bool pldm_entity_is_exist_parent(pldm_entity_node *node);
+
+/** @brief Convert entity association tree to PDR
+ *
+ *  @param[in] tree - opaque pointer to entity association tree
+ *  @param[in] repo - PDR repo where entity association records should be added
+ *  @param[in] is_remote - if true, then the PDR is not from this terminus
+ *  @param[in] terminus_handle - terminus handle of the terminus
+ */
+void pldm_entity_association_pdr_add(pldm_entity_association_tree *tree,
+				     pldm_pdr *repo, bool is_remote,
+				     uint16_t terminus_handle);
+/** @brief Add entity association pdr from node
+ *
+ *  @param[in] node - opaque pointer acting as a handle to an entity node
+ *  @param[in] repo - PDR repo where entity association records should be added
+ *  @param[in] is_remote  - if true, then the PDR is not from this terminus
+ *  @param[in] terminus_handle - terminus handle of the terminus
+ */
+void pldm_entity_association_pdr_add_from_node(
+    pldm_entity_node *node, pldm_pdr *repo, pldm_entity **entities,
+    size_t num_entities, bool is_remote, uint16_t terminus_handle);
+
+/** @brief Find entity reference in tree
+ *
+ *  @param[in] tree - opaque pointer to entity association tree
+ *  @param[in] entity - PLDM entity
+ *  @param[in] node - node to the entity
+ */
+void pldm_find_entity_ref_in_tree(pldm_entity_association_tree *tree,
+				  pldm_entity entity, pldm_entity_node **node);
+
+/** @brief Get number of children of entity
+ *
+ *  @param[in] node - opaque pointer acting as a handle to an entity node
+ *  @param[in] association_type - relation type filter : logical or physical
+ *
+ *  @return uint8_t number of children
+ */
+uint8_t pldm_entity_get_num_children(pldm_entity_node *node,
+				     uint8_t association_type);
+
+/** @brief Verify that the current node is a child of the current parent
+ *
+ *  @param[in] parent    - opaque pointer acting as a handle to an entity parent
+ *  @param[in] node      - pointer to the node of the pldm entity
+ */
+bool pldm_is_current_parent_child(pldm_entity_node *parent, pldm_entity *node);
+
+/** @brief Find an entity in the entity association tree
+ *
+ *  @param[in] tree - pointer to entity association tree
+ *  @param[in/out] entity - entity type and instance id set on input, container
+ *                 id set on output
+ *
+ *  @return pldm_entity_node* pointer to entity if found, NULL otherwise
+ */
+pldm_entity_node *
+pldm_entity_association_tree_find(pldm_entity_association_tree *tree,
+				  pldm_entity *entity);
+
+/** @brief Create a copy of an existing entity association tree
+ *
+ *  @param[in] org_tree - pointer to source tree
+ *  @param[in/out] new_tree - pointer to destination tree
+ */
+void pldm_entity_association_tree_copy_root(
+    pldm_entity_association_tree *org_tree,
+    pldm_entity_association_tree *new_tree);
+
+/** @brief Destroy all the nodes of the entity association tree
+ *
+ *  @param[in] tree - pointer to entity association tree
+ */
+void pldm_entity_association_tree_destroy_root(
+    pldm_entity_association_tree *tree);
+
+/** @brief Check whether the entity association tree is empty
+ *
+ *  @param[in] tree - pointer to entity association tree
+ *  @return bool, true if tree is empty
+ */
+bool pldm_is_empty_entity_assoc_tree(pldm_entity_association_tree *tree);
+
+/** @brief Extract entities from entity association PDR
+ *
+ *  @param[in] pdr - entity association PDR
+ *  @param[in] pdr_len - size of entity association PDR in bytes
+ *  @param[out] num_entities - number of entities found, including the container
+ *  @param[out] entities - extracted entities, container is *entities[0]. Caller
+ *              must free *entities
+ */
+void pldm_entity_association_pdr_extract(const uint8_t *pdr, uint16_t pdr_len,
+					 size_t *num_entities,
+					 pldm_entity **entities);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PDR_H */
diff --git a/include/libpldm/platform.h b/include/libpldm/platform.h
new file mode 100644
index 0000000..e03d8c2
--- /dev/null
+++ b/include/libpldm/platform.h
@@ -0,0 +1,1625 @@
+#ifndef PLATFORM_H
+#define PLATFORM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base.h"
+#include "pdr.h"
+
+/* Maximum size for request */
+#define PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES 19
+#define PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES 4
+#define PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES 2
+#define PLDM_GET_SENSOR_READING_REQ_BYTES 3
+#define PLDM_SET_EVENT_RECEIVER_REQ_BYTES 5
+/* Response lengths are inclusive of completion code */
+#define PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES 1
+
+#define PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES 1
+#define PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES 4
+
+#define PLDM_GET_PDR_REQ_BYTES 13
+
+#define PLDM_SET_EVENT_RECEIVER_RESP_BYTES 1
+/* Minimum response length */
+#define PLDM_GET_PDR_MIN_RESP_BYTES 12
+#define PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES 5
+#define PLDM_GET_SENSOR_READING_MIN_RESP_BYTES 8
+#define PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES 2
+#define PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES 41
+
+/* Minimum length for PLDM PlatformEventMessage request */
+#define PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES 3
+#define PLDM_PLATFORM_EVENT_MESSAGE_STATE_SENSOR_STATE_REQ_BYTES 6
+#define PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES 2
+#define PLDM_PLATFORM_EVENT_MESSAGE_FORMAT_VERSION 1
+
+/* Minumum length of senson event data */
+#define PLDM_SENSOR_EVENT_DATA_MIN_LENGTH 5
+#define PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH 2
+#define PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH 3
+#define PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH 4
+#define PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH 7
+#define PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_8BIT_DATA_LENGTH 4
+#define PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_16BIT_DATA_LENGTH 5
+#define PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_32BIT_DATA_LENGTH 7
+
+/* Minimum length of data for pldmPDRRepositoryChgEvent */
+#define PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH 2
+#define PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH 2
+
+#define PLDM_INVALID_EFFECTER_ID 0xFFFF
+#define PLDM_TID_RESERVED 0xFF
+
+enum pldm_effecter_data_size {
+	PLDM_EFFECTER_DATA_SIZE_UINT8,
+	PLDM_EFFECTER_DATA_SIZE_SINT8,
+	PLDM_EFFECTER_DATA_SIZE_UINT16,
+	PLDM_EFFECTER_DATA_SIZE_SINT16,
+	PLDM_EFFECTER_DATA_SIZE_UINT32,
+	PLDM_EFFECTER_DATA_SIZE_SINT32
+};
+
+enum pldm_range_field_format {
+	PLDM_RANGE_FIELD_FORMAT_UINT8,
+	PLDM_RANGE_FIELD_FORMAT_SINT8,
+	PLDM_RANGE_FIELD_FORMAT_UINT16,
+	PLDM_RANGE_FIELD_FORMAT_SINT16,
+	PLDM_RANGE_FIELD_FORMAT_UINT32,
+	PLDM_RANGE_FIELD_FORMAT_SINT32,
+	PLDM_RANGE_FIELD_FORMAT_REAL32
+};
+
+enum set_request { PLDM_NO_CHANGE = 0x00, PLDM_REQUEST_SET = 0x01 };
+
+enum effecter_state { PLDM_INVALID_VALUE = 0xFF };
+
+enum pldm_sensor_present_state {
+	PLDM_SENSOR_UNKNOWN = 0x0,
+	PLDM_SENSOR_NORMAL = 0x01,
+	PLDM_SENSOR_WARNING = 0x02,
+	PLDM_SENSOR_CRITICAL = 0x03,
+	PLDM_SENSOR_FATAL = 0x04,
+	PLDM_SENSOR_LOWERWARNING = 0x05,
+	PLDM_SENSOR_LOWERCRITICAL = 0x06,
+	PLDM_SENSOR_LOWERFATAL = 0x07,
+	PLDM_SENSOR_UPPERWARNING = 0x08,
+	PLDM_SENSOR_UPPERCRITICAL = 0x09,
+	PLDM_SENSOR_UPPERFATAL = 0x0a
+};
+
+enum pldm_sensor_event_message_enable {
+	PLDM_NO_EVENT_GENERATION,
+	PLDM_EVENTS_DISABLED,
+	PLDM_EVENTS_ENABLED,
+	PLDM_OP_EVENTS_ONLY_ENABLED,
+	PLDM_STATE_EVENTS_ONLY_ENABLED
+};
+
+enum pldm_effecter_oper_state {
+	EFFECTER_OPER_STATE_ENABLED_UPDATEPENDING,
+	EFFECTER_OPER_STATE_ENABLED_NOUPDATEPENDING,
+	EFFECTER_OPER_STATE_DISABLED,
+	EFFECTER_OPER_STATE_UNAVAILABLE,
+	EFFECTER_OPER_STATE_STATUSUNKNOWN,
+	EFFECTER_OPER_STATE_FAILED,
+	EFFECTER_OPER_STATE_INITIALIZING,
+	EFFECTER_OPER_STATE_SHUTTINGDOWN,
+	EFFECTER_OPER_STATE_INTEST
+};
+
+enum pldm_platform_commands {
+	PLDM_SET_EVENT_RECEIVER = 0x04,
+	PLDM_GET_SENSOR_READING = 0x11,
+	PLDM_GET_STATE_SENSOR_READINGS = 0x21,
+	PLDM_SET_NUMERIC_EFFECTER_VALUE = 0x31,
+	PLDM_GET_NUMERIC_EFFECTER_VALUE = 0x32,
+	PLDM_SET_STATE_EFFECTER_STATES = 0x39,
+	PLDM_GET_PDR_REPOSITORY_INFO = 0x50,
+	PLDM_GET_PDR = 0x51,
+	PLDM_PLATFORM_EVENT_MESSAGE = 0x0A
+};
+
+/** @brief PLDM PDR types
+ */
+enum pldm_pdr_types {
+	PLDM_TERMINUS_LOCATOR_PDR = 1,
+	PLDM_NUMERIC_SENSOR_PDR = 2,
+	PLDM_NUMERIC_SENSOR_INITIALIZATION_PDR = 3,
+	PLDM_STATE_SENSOR_PDR = 4,
+	PLDM_STATE_SENSOR_INITIALIZATION_PDR = 5,
+	PLDM_SENSOR_AUXILIARY_NAMES_PDR = 6,
+	PLDM_OEM_UNIT_PDR = 7,
+	PLDM_OEM_STATE_SET_PDR = 8,
+	PLDM_NUMERIC_EFFECTER_PDR = 9,
+	PLDM_NUMERIC_EFFECTER_INITIALIZATION_PDR = 10,
+	PLDM_STATE_EFFECTER_PDR = 11,
+	PLDM_STATE_EFFECTER_INITIALIZATION_PDR = 12,
+	PLDM_EFFECTER_AUXILIARY_NAMES_PDR = 13,
+	PLDM_EFFECTER_OEM_SEMANTIC_PDR = 14,
+	PLDM_PDR_ENTITY_ASSOCIATION = 15,
+	PLDM_ENTITY_AUXILIARY_NAMES_PDR = 16,
+	PLDM_OEM_ENTITY_ID_PDR = 17,
+	PLDM_INTERRUPT_ASSOCIATION_PDR = 18,
+	PLDM_EVENT_LOG_PDR = 19,
+	PLDM_PDR_FRU_RECORD_SET = 20,
+	PLDM_OEM_DEVICE_PDR = 126,
+	PLDM_OEM_PDR = 127,
+};
+
+/** @brief PLDM effecter initialization schemes
+ */
+enum pldm_effecter_init {
+	PLDM_NO_INIT,
+	PLDM_USE_INIT_PDR,
+	PLDM_ENABLE_EFFECTER,
+	PLDM_DISABLE_EFECTER
+};
+
+/** @brief PLDM Platform M&C completion codes
+ */
+enum pldm_platform_completion_codes {
+	PLDM_PLATFORM_INVALID_SENSOR_ID = 0x80,
+	PLDM_PLATFORM_REARM_UNAVAILABLE_IN_PRESENT_STATE = 0x81,
+
+	PLDM_PLATFORM_INVALID_EFFECTER_ID = 0x80,
+	PLDM_PLATFORM_INVALID_STATE_VALUE = 0x81,
+
+	PLDM_PLATFORM_INVALID_DATA_TRANSFER_HANDLE = 0x80,
+	PLDM_PLATFORM_INVALID_TRANSFER_OPERATION_FLAG = 0x81,
+	PLDM_PLATFORM_INVALID_RECORD_HANDLE = 0x82,
+	PLDM_PLATFORM_INVALID_RECORD_CHANGE_NUMBER = 0x83,
+	PLDM_PLATFORM_TRANSFER_TIMEOUT = 0x84,
+
+	PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE = 0x82,
+
+	PLDM_PLATFORM_INVALID_PROTOCOL_TYPE = 0x80,
+	PLDM_PLATFORM_ENABLE_METHOD_NOT_SUPPORTED = 0x81,
+	PLDM_PLATFORM_HEARTBEAT_FREQUENCY_TOO_HIGH = 0x82,
+};
+
+/** @brief PLDM Event types
+ */
+enum pldm_event_types {
+	PLDM_SENSOR_EVENT = 0x00,
+	PLDM_EFFECTER_EVENT = 0x01,
+	PLDM_REDFISH_TASK_EXECUTED_EVENT = 0x02,
+	PLDM_REDFISH_MESSAGE_EVENT = 0x03,
+	PLDM_PDR_REPOSITORY_CHG_EVENT = 0x04,
+	PLDM_MESSAGE_POLL_EVENT = 0x05,
+	PLDM_HEARTBEAT_TIMER_ELAPSED_EVENT = 0x06
+};
+
+/** @brief PLDM sensorEventClass states
+ */
+enum sensor_event_class_states {
+	PLDM_SENSOR_OP_STATE,
+	PLDM_STATE_SENSOR_STATE,
+	PLDM_NUMERIC_SENSOR_STATE
+};
+
+/** @brief PLDM sensor supported states
+ */
+enum pldm_sensor_operational_state {
+	PLDM_SENSOR_ENABLED,
+	PLDM_SENSOR_DISABLED,
+	PLDM_SENSOR_UNAVAILABLE,
+	PLDM_SENSOR_STATUSUNKOWN,
+	PLDM_SENSOR_FAILED,
+	PLDM_SENSOR_INITIALIZING,
+	PLDM_SENSOR_SHUTTINGDOWN,
+	PLDM_SENSOR_INTEST
+};
+
+/** @brief PLDM pldmPDRRepositoryChgEvent class eventData format
+ */
+enum pldm_pdr_repository_chg_event_data_format {
+	REFRESH_ENTIRE_REPOSITORY,
+	FORMAT_IS_PDR_TYPES,
+	FORMAT_IS_PDR_HANDLES
+};
+
+/** @brief PLDM pldmPDRRepositoryChgEvent class changeRecord format
+ * eventDataOperation
+ */
+enum pldm_pdr_repository_chg_event_change_record_event_data_operation {
+	PLDM_REFRESH_ALL_RECORDS,
+	PLDM_RECORDS_DELETED,
+	PLDM_RECORDS_ADDED,
+	PLDM_RECORDS_MODIFIED
+};
+
+/** @brief PLDM NumericSensorStatePresentReading data type
+ */
+enum pldm_sensor_readings_data_type {
+	PLDM_SENSOR_DATA_SIZE_UINT8,
+	PLDM_SENSOR_DATA_SIZE_SINT8,
+	PLDM_SENSOR_DATA_SIZE_UINT16,
+	PLDM_SENSOR_DATA_SIZE_SINT16,
+	PLDM_SENSOR_DATA_SIZE_UINT32,
+	PLDM_SENSOR_DATA_SIZE_SINT32
+};
+
+/** @brief PLDM PlatformEventMessage response status
+ */
+enum pldm_platform_event_status {
+	PLDM_EVENT_NO_LOGGING = 0x00,
+	PLDM_EVENT_LOGGING_DISABLED = 0x01,
+	PLDM_EVENT_LOG_FULL = 0x02,
+	PLDM_EVENT_ACCEPTED_FOR_LOGGING = 0x03,
+	PLDM_EVENT_LOGGED = 0x04,
+	PLDM_EVENT_LOGGING_REJECTED = 0x05
+};
+
+/** @brief PLDM Terminus Locator PDR validity
+ */
+enum pldm_terminus_locator_pdr_validity {
+	PLDM_TL_PDR_NOT_VALID,
+	PLDM_TL_PDR_VALID
+};
+
+/** @brief PLDM Terminus Locator type
+ */
+enum pldm_terminus_locator_type {
+	PLDM_TERMINUS_LOCATOR_TYPE_UID,
+	PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID,
+	PLDM_TERMINUS_LOCATOR_TYPE_SMBUS_RELATIVE,
+	PLDM_TERMINUS_LOCATOR_TYPE_SYS_SW
+};
+
+/** @brief PLDM event message global enable for
+ *  SetEventReceiver command
+ */
+enum pldm_event_message_global_enable {
+	PLDM_EVENT_MESSAGE_GLOBAL_DISABLE,
+	PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC,
+	PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_POLLING,
+	PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE
+};
+
+/** @brief PLDM respository state */
+enum pldm_repository_state {
+	PLDM_AVAILABLE,
+	PLDM_UPDATE_IN_PROGRESS,
+	PLDM_FAILED
+};
+
+/** @brief PLDM respository data transfer handler timeout */
+enum pldm_repository_data_transfer_handler_timeout {
+	PLDM_NO_TIMEOUT,
+	PLDM_DEFALUT_MINIMUM_TIMEOUT
+};
+
+/** @struct pldm_pdr_hdr
+ *
+ *  Structure representing PLDM common PDR header
+ */
+struct pldm_pdr_hdr {
+	uint32_t record_handle;
+	uint8_t version;
+	uint8_t type;
+	uint16_t record_change_num;
+	uint16_t length;
+} __attribute__((packed));
+
+/** @struct pldm_terminus_locator_pdr
+ *
+ *  Structure representing PLDM terminus locator PDR
+ */
+struct pldm_terminus_locator_pdr {
+	struct pldm_pdr_hdr hdr;
+	uint16_t terminus_handle;
+	uint8_t validity;
+	uint8_t tid;
+	uint16_t container_id;
+	uint8_t terminus_locator_type;
+	uint8_t terminus_locator_value_size;
+	uint8_t terminus_locator_value[1];
+} __attribute__((packed));
+
+/** @struct pldm_terminus_locator_type_mctp_eid
+ *
+ *  Structure representing terminus locator value for
+ *  terminus locator type MCTP_EID
+ */
+struct pldm_terminus_locator_type_mctp_eid {
+	uint8_t eid;
+} __attribute__((packed));
+
+/** @struct pldm_pdr_entity_association
+ *
+ *  Structure representing PLDM Entity Association PDR
+ */
+struct pldm_pdr_entity_association {
+	uint16_t container_id;
+	uint8_t association_type;
+	pldm_entity container;
+	uint8_t num_children;
+	pldm_entity children[1];
+} __attribute__((packed));
+
+/** @struct pldm_pdr_fru_record_set
+ *
+ *  Structure representing PLDM FRU record set PDR
+ */
+struct pldm_pdr_fru_record_set {
+	uint16_t terminus_handle;
+	uint16_t fru_rsi;
+	uint16_t entity_type;
+	uint16_t entity_instance_num;
+	uint16_t container_id;
+} __attribute__((packed));
+
+/** @struct pldm_state_sensor_pdr
+ *
+ *  Structure representing PLDM state sensor PDR
+ */
+struct pldm_state_sensor_pdr {
+	struct pldm_pdr_hdr hdr;
+	uint16_t terminus_handle;
+	uint16_t sensor_id;
+	uint16_t entity_type;
+	uint16_t entity_instance;
+	uint16_t container_id;
+	uint8_t sensor_init;
+	bool8_t sensor_auxiliary_names_pdr;
+	uint8_t composite_sensor_count;
+	uint8_t possible_states[1];
+} __attribute__((packed));
+
+/** @struct state_sensor_possible_states
+ *
+ *  Structure representing state enums for state sensor
+ */
+struct state_sensor_possible_states {
+	uint16_t state_set_id;
+	uint8_t possible_states_size;
+	bitfield8_t states[1];
+} __attribute__((packed));
+
+/** @struct pldm_state_effecter_pdr
+ *
+ *  Structure representing PLDM state effecter PDR
+ */
+struct pldm_state_effecter_pdr {
+	struct pldm_pdr_hdr hdr;
+	uint16_t terminus_handle;
+	uint16_t effecter_id;
+	uint16_t entity_type;
+	uint16_t entity_instance;
+	uint16_t container_id;
+	uint16_t effecter_semantic_id;
+	uint8_t effecter_init;
+	bool8_t has_description_pdr;
+	uint8_t composite_effecter_count;
+	uint8_t possible_states[1];
+} __attribute__((packed));
+
+/** @brief Encode PLDM state sensor PDR
+ *
+ * @param[in/out] sensor                 Structure to encode. All members of
+ * sensor, except those mentioned in the @note below, should be initialized by
+ * the caller.
+ * @param[in]     allocation_size        Size of sensor allocation in bytes
+ * @param[in]     possible_states        Possible sensor states
+ * @param[in]     possible_states_size   Size of possible sensor states in bytes
+ * @param[out]    actual_size            Size of sensor PDR. Set to 0 on error.
+ * @return int    pldm_completion_codes
+ *                PLDM_SUCCESS/PLDM_ERROR/PLDM_ERROR_INVALID_LENGTH
+ *
+ * @note The sensor parameter will be encoded in place.
+ * @note Caller is responsible for allocation of the sensor parameter. Caller
+ *       must allocate enough space for the base structure and the
+ *       sensor->possible_states array, otherwise the function will fail.
+ * @note sensor->hdr.length, .type, and .version will be set appropriately.
+ */
+int encode_state_sensor_pdr(
+    struct pldm_state_sensor_pdr *sensor, size_t allocation_size,
+    const struct state_sensor_possible_states *possible_states,
+    size_t possible_states_size, size_t *actual_size);
+
+/** @union union_effecter_data_size
+ *
+ *  The bit width and format of reading and threshold values that the effecter
+ *  returns.
+ *  Refer to: DSP0248_1.2.0: 28.11 Table 87
+ */
+typedef union {
+	uint8_t value_u8;
+	int8_t value_s8;
+	uint16_t value_u16;
+	int16_t value_s16;
+	uint32_t value_u32;
+	int32_t value_s32;
+} union_effecter_data_size;
+
+/** @union union_range_field_format
+ *
+ *  Indicates the format used for the nominalValue, normalMax, and normalMin
+ *  fields.
+ *  Refer to: DSP0248_1.2.0: 28.11 Table 87
+ */
+typedef union {
+	uint8_t value_u8;
+	int8_t value_s8;
+	uint16_t value_u16;
+	int16_t value_s16;
+	uint32_t value_u32;
+	int32_t value_s32;
+	real32_t value_f32;
+} union_range_field_format;
+
+/** @struct pldm_numeric_effecter_value_pdr
+ *
+ *  Structure representing PLDM numeric effecter value PDR
+ */
+struct pldm_numeric_effecter_value_pdr {
+	struct pldm_pdr_hdr hdr;
+	uint16_t terminus_handle;
+	uint16_t effecter_id;
+	uint16_t entity_type;
+	uint16_t entity_instance;
+	uint16_t container_id;
+	uint16_t effecter_semantic_id;
+	uint8_t effecter_init;
+	bool8_t effecter_auxiliary_names;
+	uint8_t base_unit;
+	int8_t unit_modifier;
+	uint8_t rate_unit;
+	uint8_t base_oem_unit_handle;
+	uint8_t aux_unit;
+	int8_t aux_unit_modifier;
+	uint8_t aux_rate_unit;
+	uint8_t aux_oem_unit_handle;
+	bool8_t is_linear;
+	uint8_t effecter_data_size;
+	real32_t resolution;
+	real32_t offset;
+	uint16_t accuracy;
+	uint8_t plus_tolerance;
+	uint8_t minus_tolerance;
+	real32_t state_transition_interval;
+	real32_t transition_interval;
+	union_effecter_data_size max_settable;
+	union_effecter_data_size min_settable;
+	uint8_t range_field_format;
+	bitfield8_t range_field_support;
+	union_range_field_format nominal_value;
+	union_range_field_format normal_max;
+	union_range_field_format normal_min;
+	union_range_field_format rated_max;
+	union_range_field_format rated_min;
+} __attribute__((packed));
+
+/** @struct state_effecter_possible_states
+ *
+ *  Structure representing state enums for state effecter
+ */
+struct state_effecter_possible_states {
+	uint16_t state_set_id;
+	uint8_t possible_states_size;
+	bitfield8_t states[1];
+} __attribute__((packed));
+
+/** @brief Encode PLDM state effecter PDR
+ *
+ * @param[in/out] effecter               Structure to encode. All members of
+ *                                       effecter, except those mentioned in
+ *                                       the @note below, should be initialized
+ *                                       by the caller.
+ * @param[in]     allocation_size        Size of effecter allocation in bytes
+ * @param[in]     possible_states        Possible effecter states
+ * @param[in]     possible_states_size   Size of possible effecter states in
+ *                                       bytes
+ * @param[out]    actual_size            Size of effecter PDR. Set to 0 on
+ *                                       error.
+ * @return int    pldm_completion_codes
+ *                PLDM_SUCCESS/PLDM_ERROR/PLDM_ERROR_INVALID_LENGTH
+ *
+ * @note The effecter parameter will be encoded in place.
+ * @note Caller is responsible for allocation of the effecter parameter. Caller
+ *       must allocate enough space for the base structure and the
+ *       effecter->possible_states array, otherwise the function will fail.
+ * @note effecter->hdr.length, .type, and .version will be set appropriately.
+ */
+int encode_state_effecter_pdr(
+    struct pldm_state_effecter_pdr *effecter, size_t allocation_size,
+    const struct state_effecter_possible_states *possible_states,
+    size_t possible_states_size, size_t *actual_size);
+
+/** @struct set_effecter_state_field
+ *
+ *  Structure representing a stateField in SetStateEffecterStates command */
+
+typedef struct state_field_for_state_effecter_set {
+	uint8_t set_request;	//!< Whether to change the state
+	uint8_t effecter_state; //!< Expected state of the effecter
+} __attribute__((packed)) set_effecter_state_field;
+
+/** @struct get_sensor_readings_field
+ *
+ *  Structure representing a stateField in GetStateSensorReadings command */
+
+typedef struct state_field_for_get_state_sensor_readings {
+	uint8_t sensor_op_state; //!< The state of the sensor itself
+	uint8_t present_state;	 //!< Return a state value
+	uint8_t previous_state; //!< The state that the presentState was entered
+				//! from. This must be different from the
+				//! present state
+	uint8_t event_state;	//!< Return a state value from a PLDM State Set
+			     //! that is associated with the sensor
+} __attribute__((packed)) get_sensor_state_field;
+
+/** @struct PLDM_SetStateEffecterStates_Request
+ *
+ *  Structure representing PLDM set state effecter states request.
+ */
+struct pldm_set_state_effecter_states_req {
+	uint16_t effecter_id;
+	uint8_t comp_effecter_count;
+	set_effecter_state_field field[8];
+} __attribute__((packed));
+
+/** @struct pldm_get_pdr_repository_info_resp
+ *
+ *  Structure representing GetPDRRepositoryInfo response packet
+ */
+struct pldm_pdr_repository_info_resp {
+	uint8_t completion_code;
+	uint8_t repository_state;
+	uint8_t update_time[PLDM_TIMESTAMP104_SIZE];
+	uint8_t oem_update_time[PLDM_TIMESTAMP104_SIZE];
+	uint32_t record_count;
+	uint32_t repository_size;
+	uint32_t largest_record_size;
+	uint8_t data_transfer_handle_timeout;
+} __attribute__((packed));
+
+/** @struct pldm_get_pdr_resp
+ *
+ *  structure representing GetPDR response packet
+ *  transfer CRC is not part of the structure and will be
+ *  added at the end of last packet in multipart transfer
+ */
+struct pldm_get_pdr_resp {
+	uint8_t completion_code;
+	uint32_t next_record_handle;
+	uint32_t next_data_transfer_handle;
+	uint8_t transfer_flag;
+	uint16_t response_count;
+	uint8_t record_data[1];
+} __attribute__((packed));
+
+/** @struct pldm_get_pdr_req
+ *
+ *  structure representing GetPDR request packet
+ */
+struct pldm_get_pdr_req {
+	uint32_t record_handle;
+	uint32_t data_transfer_handle;
+	uint8_t transfer_op_flag;
+	uint16_t request_count;
+	uint16_t record_change_number;
+} __attribute__((packed));
+
+/** @struct pldm_set_event_receiver_req
+ *
+ * Structure representing SetEventReceiver command.
+ * This structure applies only for MCTP as a transport type.
+ */
+struct pldm_set_event_receiver_req {
+	uint8_t event_message_global_enable;
+	uint8_t transport_protocol_type;
+	uint8_t event_receiver_address_info;
+	uint16_t heartbeat_timer;
+} __attribute__((packed));
+
+/** @struct pldm_set_numeric_effecter_value_req
+ *
+ *  structure representing SetNumericEffecterValue request packet
+ */
+struct pldm_set_numeric_effecter_value_req {
+	uint16_t effecter_id;
+	uint8_t effecter_data_size;
+	uint8_t effecter_value[1];
+} __attribute__((packed));
+
+/** @struct pldm_get_state_sensor_readings_req
+ *
+ *  Structure representing PLDM get state sensor readings request.
+ */
+struct pldm_get_state_sensor_readings_req {
+	uint16_t sensor_id;
+	bitfield8_t sensor_rearm;
+	uint8_t reserved;
+} __attribute__((packed));
+
+/** @struct pldm_get_state_sensor_readings_resp
+ *
+ *  Structure representing PLDM get state sensor readings response.
+ */
+struct pldm_get_state_sensor_readings_resp {
+	uint8_t completion_code;
+	uint8_t comp_sensor_count;
+	get_sensor_state_field field[1];
+} __attribute__((packed));
+
+/** @struct pldm_sensor_event
+ *
+ *  structure representing sensorEventClass
+ */
+struct pldm_sensor_event_data {
+	uint16_t sensor_id;
+	uint8_t sensor_event_class_type;
+	uint8_t event_class[1];
+} __attribute__((packed));
+
+/** @struct pldm_state_sensor_state
+ *
+ *  structure representing sensorEventClass for stateSensorState
+ */
+struct pldm_sensor_event_state_sensor_state {
+	uint8_t sensor_offset;
+	uint8_t event_state;
+	uint8_t previous_event_state;
+} __attribute__((packed));
+
+/** @struct pldm_sensor_event_numeric_sensor_state
+ *
+ *  structure representing sensorEventClass for stateSensorState
+ */
+struct pldm_sensor_event_numeric_sensor_state {
+	uint8_t event_state;
+	uint8_t previous_event_state;
+	uint8_t sensor_data_size;
+	uint8_t present_reading[1];
+} __attribute__((packed));
+
+/** @struct pldm_sensor_event_sensor_op_state
+ *
+ *  structure representing sensorEventClass for SensorOpState
+ */
+struct pldm_sensor_event_sensor_op_state {
+	uint8_t present_op_state;
+	uint8_t previous_op_state;
+} __attribute__((packed));
+
+/** @struct pldm_platform_event_message_req
+ *
+ *  structure representing PlatformEventMessage command request data
+ */
+struct pldm_platform_event_message_req {
+	uint8_t format_version;
+	uint8_t tid;
+	uint8_t event_class;
+	uint8_t event_data[1];
+} __attribute__((packed));
+
+/** @struct pldm_platform_event_message_response
+ *
+ *  structure representing PlatformEventMessage command response data
+ */
+struct pldm_platform_event_message_resp {
+	uint8_t completion_code;
+	uint8_t platform_event_status;
+} __attribute__((packed));
+
+/** @struct pldm_pdr_repository_chg_event_data
+ *
+ *  structure representing pldmPDRRepositoryChgEvent class eventData
+ */
+struct pldm_pdr_repository_chg_event_data {
+	uint8_t event_data_format;
+	uint8_t number_of_change_records;
+	uint8_t change_records[1];
+} __attribute__((packed));
+
+/** @struct pldm_pdr_repository_chg_event_change_record_data
+ *
+ *  structure representing pldmPDRRepositoryChgEvent class eventData's change
+ * record data
+ */
+struct pldm_pdr_repository_change_record_data {
+	uint8_t event_data_operation;
+	uint8_t number_of_change_entries;
+	uint32_t change_entry[1];
+} __attribute__((packed));
+
+/** @struct pldm_get_numeric_effecter_value_req
+ *
+ *  structure representing GetNumericEffecterValue request packet
+ */
+struct pldm_get_numeric_effecter_value_req {
+	uint16_t effecter_id;
+} __attribute__((packed));
+
+/** @struct pldm_get_numeric_effecter_value_resp
+ *
+ *  structure representing GetNumericEffecterValue response packet
+ */
+struct pldm_get_numeric_effecter_value_resp {
+	uint8_t completion_code;
+	uint8_t effecter_data_size;
+	uint8_t effecter_oper_state;
+	uint8_t pending_and_present_values[1];
+} __attribute__((packed));
+
+/** @struct pldm_get_sensor_reading_req
+ *
+ *  Structure representing PLDM get sensor reading request
+ */
+struct pldm_get_sensor_reading_req {
+	uint16_t sensor_id;
+	bool8_t rearm_event_state;
+} __attribute__((packed));
+
+/** @struct pldm_get_sensor_reading_resp
+ *
+ *  Structure representing PLDM get sensor reading response
+ */
+struct pldm_get_sensor_reading_resp {
+	uint8_t completion_code;
+	uint8_t sensor_data_size;
+	uint8_t sensor_operational_state;
+	uint8_t sensor_event_message_enable;
+	uint8_t present_state;
+	uint8_t previous_state;
+	uint8_t event_state;
+	uint8_t present_reading[1];
+} __attribute__((packed));
+
+/* Responder */
+
+/* SetNumericEffecterValue */
+
+/** @brief Decode SetNumericEffecterValue request data
+ *
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - Length of request message payload
+ *  @param[out] effecter_id - used to identify and access the effecter
+ *  @param[out] effecter_data_size - The bit width and format of the setting
+ * 				value for the effecter.
+ * 				value:{uint8,sint8,uint16,sint16,uint32,sint32}
+ *  @param[out] effecter_value - The setting value of numeric effecter being
+ * 				requested.
+ *  @return pldm_completion_codes
+ */
+int decode_set_numeric_effecter_value_req(const struct pldm_msg *msg,
+					  size_t payload_length,
+					  uint16_t *effecter_id,
+					  uint8_t *effecter_data_size,
+					  uint8_t *effecter_value);
+
+/** @brief Create a PLDM response message for SetNumericEffecterValue
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[out] msg - Message will be written to this
+ *  @param[in] payload_length - Length of request message payload
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.body.payload'
+ */
+int encode_set_numeric_effecter_value_resp(uint8_t instance_id,
+					   uint8_t completion_code,
+					   struct pldm_msg *msg,
+					   size_t payload_length);
+
+/* SetStateEffecterStates */
+
+/** @brief Create a PLDM response message for SetStateEffecterStates
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.body.payload'
+ */
+
+int encode_set_state_effecter_states_resp(uint8_t instance_id,
+					  uint8_t completion_code,
+					  struct pldm_msg *msg);
+
+/** @brief Decode SetStateEffecterStates request data
+ *
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - Length of request message payload
+ *  @param[out] effecter_id - used to identify and access the effecter
+ *  @param[out] comp_effecter_count - number of individual sets of effecter
+ *         information. Upto eight sets of state effecter info can be accessed
+ *         for a given effecter.
+ *  @param[out] field - each unit is an instance of the stateFileld structure
+ *         that is used to set the requested state for a particular effecter
+ *         within the state effecter. This field holds the starting address of
+ *         the stateField values. The user is responsible to allocate the
+ *         memory prior to calling this command. Since the state field count is
+ *         not known in advance, the user should allocate the maximum size
+ *         always, which is 8 in number.
+ *  @return pldm_completion_codes
+ */
+
+int decode_set_state_effecter_states_req(const struct pldm_msg *msg,
+					 size_t payload_length,
+					 uint16_t *effecter_id,
+					 uint8_t *comp_effecter_count,
+					 set_effecter_state_field *field);
+
+/* GetPDR */
+
+/** @brief Create a PLDM response message for GetPDR
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in] next_record_hndl - The recordHandle for the PDR that is next in
+ *        the PDR Repository
+ *  @param[in] next_data_transfer_hndl - A handle that identifies the next
+ *        portion of the PDR data to be transferred, if any
+ *  @param[in] transfer_flag - Indicates the portion of PDR data being
+ *        transferred
+ *  @param[in] resp_cnt - The number of recordData bytes returned in this
+ *        response
+ *  @param[in] record_data - PDR data bytes of length resp_cnt
+ *  @param[in] transfer_crc - A CRC-8 for the overall PDR. This is present only
+ *        in the last part of a PDR being transferred
+ *  @param[out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_get_pdr_resp(uint8_t instance_id, uint8_t completion_code,
+			uint32_t next_record_hndl,
+			uint32_t next_data_transfer_hndl, uint8_t transfer_flag,
+			uint16_t resp_cnt, const uint8_t *record_data,
+			uint8_t transfer_crc, struct pldm_msg *msg);
+
+/** @brief Decode GetPDR request data
+ *
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - Length of request message payload
+ *  @param[out] record_hndl - The recordHandle value for the PDR to be retrieved
+ *  @param[out] data_transfer_hndl - Handle used to identify a particular
+ *         multipart PDR data transfer operation
+ *  @param[out] transfer_op_flag - Flag to indicate the first or subsequent
+ *         portion of transfer
+ *  @param[out] request_cnt - The maximum number of record bytes requested
+ *  @param[out] record_chg_num - Used to determine whether the PDR has changed
+ *        while PDR transfer is going on
+ *  @return pldm_completion_codes
+ */
+
+int decode_get_pdr_req(const struct pldm_msg *msg, size_t payload_length,
+		       uint32_t *record_hndl, uint32_t *data_transfer_hndl,
+		       uint8_t *transfer_op_flag, uint16_t *request_cnt,
+		       uint16_t *record_chg_num);
+
+/* GetStateSensorReadings */
+
+/** @brief Decode GetStateSensorReadings request data
+ *
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - Length of request message payload
+ *  @param[out] sensor_id - used to identify and access the simple or composite
+ *         sensor
+ *  @param[out] sensor_rearm - Each bit location in this field corresponds to a
+ *         particular sensor within the state sensor, where bit [0] corresponds
+ *         to the first state sensor (sensor offset 0) and bit [7] corresponds
+ *         to the eighth sensor (sensor offset 7), sequentially.
+ *  @param[out] reserved - value: 0x00
+ *  @return pldm_completion_codes
+ */
+
+int decode_get_state_sensor_readings_req(const struct pldm_msg *msg,
+					 size_t payload_length,
+					 uint16_t *sensor_id,
+					 bitfield8_t *sensor_rearm,
+					 uint8_t *reserved);
+
+/** @brief Encode GetStateSensorReadings response data
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[out] comp_sensor_count - The number of individual sets of sensor
+ *         information that this command accesses
+ *  @param[out] field - Each stateField is an instance of a stateField structure
+ *         that is used to return the present operational state setting and the
+ *         present state and event state for a particular set of sensor
+ *         information contained within the state sensor
+ *  @param[out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ */
+
+int encode_get_state_sensor_readings_resp(uint8_t instance_id,
+					  uint8_t completion_code,
+					  uint8_t comp_sensor_count,
+					  get_sensor_state_field *field,
+					  struct pldm_msg *msg);
+
+/* GetNumericEffecterValue */
+
+/** @brief Decode GetNumericEffecterValue request data
+ *
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - Length of request message payload
+ *  @param[out] effecter_id - used to identify and access the effecter
+ *  @return pldm_completion_codes
+ */
+int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg,
+					  size_t payload_length,
+					  uint16_t *effecter_id);
+
+/** @brief Create a PLDM response message for GetNumericEffecterValue
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in] effecter_data_size - The bit width and format of the setting
+ *             value for the effecter.
+ * 	       value:{uint8,sint8,uint16,sint16,uint32,sint32}
+ *  @param[in] effecter_oper_state - The state of the effecter itself
+ *  @param[in] pending_value - The pending numeric value setting of the
+ *             effecter. The effecterDataSize field indicates the number of
+ *             bits used for this field
+ *  @param[in] present_value - The present numeric value setting of the
+ *             effecter. The effecterDataSize indicates the number of bits
+ *             used for this field
+ *  @param[out] msg - Message will be written to this
+ *  @param[in] payload_length - Length of request message payload
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_get_numeric_effecter_value_resp(
+    uint8_t instance_id, uint8_t completion_code, uint8_t effecter_data_size,
+    uint8_t effecter_oper_state, uint8_t *pending_value, uint8_t *present_value,
+    struct pldm_msg *msg, size_t payload_length);
+
+/* GetSensorReading */
+
+/** @brief Decode GetSensorReading request data
+ *
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - Length of request message payload
+ *  @param[out] sensor_id - A handle that is used to identify and access
+ *         the sensor
+ *  @param[out] rearm_event_state - true =  manually re-arm EventState after
+ *         responding to this request, false = no manual re-arm
+ *  @return pldm_completion_codes
+ */
+
+int decode_get_sensor_reading_req(const struct pldm_msg *msg,
+				  size_t payload_length, uint16_t *sensor_id,
+				  bool8_t *rearm_event_state);
+
+/** @brief Encode GetSensorReading response data
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[out] sensor_data_size - The bit width and format of reading and
+ *         threshold values
+ *  @param[out] sensor_operational_state - The state of the sensor itself
+ *  @param[out] sensor_event_message_enable - value: { noEventGeneration,
+ *         eventsDisabled, eventsEnabled, opEventsOnlyEnabled,
+ *         stateEventsOnlyEnabled }
+ *  @param[out] present_state - The most recently assessed state value monitored
+ *         by the sensor
+ *  @param[out] previous_state - The state that the presentState was entered
+ *         from
+ *  @param[out] event_state - Indicates which threshold crossing assertion
+ *         events have been detected
+ *  @param[out] present_reading - The present value indicated by the sensor
+ *  @param[out] msg - Message will be written to this
+ *  @param[in] payload_length - Length of request message payload
+ *  @return pldm_completion_codes
+ */
+
+int encode_get_sensor_reading_resp(
+    uint8_t instance_id, uint8_t completion_code, uint8_t sensor_data_size,
+    uint8_t sensor_operational_state, uint8_t sensor_event_message_enable,
+    uint8_t present_state, uint8_t previous_state, uint8_t event_state,
+    uint8_t *present_reading, struct pldm_msg *msg, size_t payload_length);
+
+/* Requester */
+
+/*GetPDRRepositoryInfo*/
+
+/** @brief Encode GetPDRRepositoryInfo response data
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in] repository_state - PLDM repository state
+ *  @param[in] update_time - When the standard PDR repository data was
+ *                           originally created
+ *  @param[in] oem_update_time - when OEM PDRs in the PDR Repository were
+ *                               originally created
+ *  @param[in] record_count - Total number of PDRs in this repository
+ *  @param[in] repository_size - Size of the PDR Repository in bytes
+ *  @param[in] largest_record_size - Size of the largest record in the PDR
+ * Repository in bytes
+ *  @param[in] data_transfer_handle_timeout - Data transmission timeout
+ *  @param[out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ */
+int encode_get_pdr_repository_info_resp(
+    uint8_t instance_id, uint8_t completion_code, uint8_t repository_state,
+    const uint8_t *update_time, const uint8_t *oem_update_time,
+    uint32_t record_count, uint32_t repository_size,
+    uint32_t largest_record_size, uint8_t data_transfer_handle_timeout,
+    struct pldm_msg *msg);
+
+/* GetPDR */
+
+/** @brief Create a PLDM request message for GetPDR
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] record_hndl - The recordHandle value for the PDR to be retrieved
+ *  @param[in] data_transfer_hndl - Handle used to identify a particular
+ *         multipart PDR data transfer operation
+ *  @param[in] transfer_op_flag - Flag to indicate the first or subsequent
+ *         portion of transfer
+ *  @param[in] request_cnt - The maximum number of record bytes requested
+ *  @param[in] record_chg_num - Used to determine whether the PDR has changed
+ *        while PDR transfer is going on
+ *  @param[out] msg - Message will be written to this
+ *  @param[in] payload_length - Length of request message payload
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_get_pdr_req(uint8_t instance_id, uint32_t record_hndl,
+		       uint32_t data_transfer_hndl, uint8_t transfer_op_flag,
+		       uint16_t request_cnt, uint16_t record_chg_num,
+		       struct pldm_msg *msg, size_t payload_length);
+
+/** @brief Decode GetPDR response data
+ *
+ *  Note:
+ *  * If the return value is not PLDM_SUCCESS, it represents a
+ * transport layer error.
+ *  * If the completion_code value is not PLDM_SUCCESS, it represents a
+ * protocol layer error and all the out-parameters are invalid.
+ *
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - Length of request message payload
+ *  @param[out] completion_code - PLDM completion code
+ *  @param[out] next_record_hndl - The recordHandle for the PDR that is next in
+ *        the PDR Repository
+ *  @param[out] next_data_transfer_hndl - A handle that identifies the next
+ *        portion of the PDR data to be transferred, if any
+ *  @param[out] transfer_flag - Indicates the portion of PDR data being
+ *        transferred
+ *  @param[out] resp_cnt - The number of recordData bytes returned in this
+ *        response
+ *  @param[out] record_data - PDR data bytes of length resp_cnt, or NULL to
+ *        skip the copy and place the actual length in resp_cnt.
+ *  @param[in] record_data_length - Length of record_data
+ *  @param[out] transfer_crc - A CRC-8 for the overall PDR. This is present only
+ *        in the last part of a PDR being transferred
+ *  @return pldm_completion_codes
+ */
+int decode_get_pdr_resp(const struct pldm_msg *msg, size_t payload_length,
+			uint8_t *completion_code, uint32_t *next_record_hndl,
+			uint32_t *next_data_transfer_hndl,
+			uint8_t *transfer_flag, uint16_t *resp_cnt,
+			uint8_t *record_data, size_t record_data_length,
+			uint8_t *transfer_crc);
+
+/* SetStateEffecterStates */
+
+/** @brief Create a PLDM request message for SetStateEffecterStates
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] effecter_id - used to identify and access the effecter
+ *  @param[in] comp_effecter_count - number of individual sets of effecter
+ *         information. Upto eight sets of state effecter info can be accessed
+ *         for a given effecter.
+ *  @param[in] field - each unit is an instance of the stateField structure
+ *         that is used to set the requested state for a particular effecter
+ *         within the state effecter. This field holds the starting address of
+ *         the stateField values. The user is responsible to allocate the
+ *         memory prior to calling this command. The user has to allocate the
+ *         field parameter as sizeof(set_effecter_state_field) *
+ *         comp_effecter_count
+ *  @param[out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+
+int encode_set_state_effecter_states_req(uint8_t instance_id,
+					 uint16_t effecter_id,
+					 uint8_t comp_effecter_count,
+					 set_effecter_state_field *field,
+					 struct pldm_msg *msg);
+
+/** @brief Decode SetStateEffecterStates response data
+ *
+ *  Note:
+ *  * If the return value is not PLDM_SUCCESS, it represents a
+ * transport layer error.
+ *  * If the completion_code value is not PLDM_SUCCESS, it represents a
+ * protocol layer error and all the out-parameters are invalid.
+ *
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[out] completion_code - PLDM completion code
+ *  @return pldm_completion_codes
+ */
+int decode_set_state_effecter_states_resp(const struct pldm_msg *msg,
+					  size_t payload_length,
+					  uint8_t *completion_code);
+
+/* SetNumericEffecterValue */
+
+/** @brief Create a PLDM request message for SetNumericEffecterValue
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] effecter_id - used to identify and access the effecter
+ *  @param[in] effecter_data_size - The bit width and format of the setting
+ * 				value for the effecter.
+ * 				value:{uint8,sint8,uint16,sint16,uint32,sint32}
+ *  @param[in] effecter_value - The setting value of numeric effecter being
+ * 				requested.
+ *  @param[in] payload_length - Length of request message payload
+ *  @param[out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_set_numeric_effecter_value_req(
+    uint8_t instance_id, uint16_t effecter_id, uint8_t effecter_data_size,
+    uint8_t *effecter_value, struct pldm_msg *msg, size_t payload_length);
+
+/** @brief Decode SetNumericEffecterValue response data
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[out] completion_code - PLDM completion code
+ *  @return pldm_completion_codes
+ */
+int decode_set_numeric_effecter_value_resp(const struct pldm_msg *msg,
+					   size_t payload_length,
+					   uint8_t *completion_code);
+
+/** @brief Create a PLDM request message for GetStateSensorReadings
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] sensor_id - used to identify and access the simple or composite
+ *         sensor
+ *  @param[in] sensorRearm - Each bit location in this field corresponds to a
+ *         particular sensor within the state sensor, where bit [0] corresponds
+ *         to the first state sensor (sensor offset 0) and bit [7] corresponds
+ *         to the eighth sensor (sensor offset 7), sequentially
+ *  @param[in] reserved - value: 0x00
+ *  @param[out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_get_state_sensor_readings_req(uint8_t instance_id,
+					 uint16_t sensor_id,
+					 bitfield8_t sensor_rearm,
+					 uint8_t reserved,
+					 struct pldm_msg *msg);
+
+/** @brief Decode GetStateSensorReadings response data
+ *
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[out] completion_code - PLDM completion code
+ *  @param[in,out] comp_sensor_count - The number of individual sets of sensor
+ *         information that this command accesses
+ *  @param[out] field - Each stateField is an instance of a stateField structure
+ *         that is used to return the present operational state setting and the
+ *         present state and event state for a particular set of sensor
+ *         information contained within the state sensor
+ *  @return pldm_completion_codes
+ */
+
+int decode_get_state_sensor_readings_resp(const struct pldm_msg *msg,
+					  size_t payload_length,
+					  uint8_t *completion_code,
+					  uint8_t *comp_sensor_count,
+					  get_sensor_state_field *field);
+
+/* PlatformEventMessage */
+
+/** @brief Decode PlatformEventMessage request data
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[out] format_version - Version of the event format
+ *  @param[out] tid - Terminus ID for the terminus that originated the event
+ * message
+ *  @param[out] event_class - The class of event being sent
+ *  @param[out] event_data_offset - Offset where the event data should be read
+ * from pldm msg
+ *  @return pldm_completion_codes
+ */
+int decode_platform_event_message_req(const struct pldm_msg *msg,
+				      size_t payload_length,
+				      uint8_t *format_version, uint8_t *tid,
+				      uint8_t *event_class,
+				      size_t *event_data_offset);
+
+/** @brief Encode PlatformEventMessage response data
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in] platform_event_status - Response status of the event message
+ * command
+ *  @param[out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_platform_event_message_resp(uint8_t instance_id,
+				       uint8_t completion_code,
+				       uint8_t platform_event_status,
+				       struct pldm_msg *msg);
+
+/** @brief Encode PlatformEventMessage request data
+ * @param[in] instance_id - Message's instance id
+ * @param[in] format_version - Version of the event format
+ * @param[in] tid - Terminus ID for the terminus that originated the event
+ * message
+ * @param[in] event_class - The class of event being sent
+ * @param[in] event_data - the event data should be read from pldm msg
+ * @param[in] event_data_length - Length of the event data
+ * @param[out] msg - Request message
+ * @return pldm_completion_codes
+ * @note Caller is responsible for memory alloc and dealloc of param
+ * 'msg.payload'
+ */
+int encode_platform_event_message_req(
+    uint8_t instance_id, uint8_t format_version, uint8_t tid,
+    uint8_t event_class, const uint8_t *event_data, size_t event_data_length,
+    struct pldm_msg *msg, size_t payload_length);
+
+/** @brief Decode PlatformEventMessage response data
+ * @param[in] msg - Request message
+ * @param[in] payload_length - Length of Response message payload
+ * @param[out] completion_code - PLDM completion code
+ * @param[out] platform_event_status - Response status of the event message
+ * command
+ * @return pldm_completion_codes
+ */
+int decode_platform_event_message_resp(const struct pldm_msg *msg,
+				       size_t payload_length,
+				       uint8_t *completion_code,
+				       uint8_t *platform_event_status);
+
+/** @brief Decode sensorEventData response data
+ *
+ *  @param[in] event_data - event data from the response message
+ *  @param[in] event_data_length - length of the event data
+ *  @param[out] sensor_id -  sensorID value of the sensor
+ *  @param[out] sensor_event_class_type - Type of sensor event class
+ *  @param[out] event_class_data_offset - Offset where the event class data
+ * should be read from event data
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'event_data'
+ */
+int decode_sensor_event_data(const uint8_t *event_data,
+			     size_t event_data_length, uint16_t *sensor_id,
+			     uint8_t *sensor_event_class_type,
+			     size_t *event_class_data_offset);
+
+/** @brief Decode sensorOpState response data
+ *
+ *  @param[in] sensor_data - sensor_data for sensorEventClass = sensorOpState
+ *  @param[in] sensor_data_length - Length of sensor_data
+ *  @param[out] present_op_state - The sensorOperationalState value from the
+ * state change that triggered the event message
+ *  @param[out] previous_op_state - The sensorOperationalState value for the
+ * state from which the present state was entered
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'sensor_data'
+ */
+int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length,
+			  uint8_t *present_op_state,
+			  uint8_t *previous_op_state);
+
+/** @brief Decode stateSensorState response data
+ *
+ *  @param[in] sensor_data - sensor_data for sensorEventClass = stateSensorState
+ *  @param[in] sensor_data_length - Length of sensor_data
+ *  @param[out] sensor_offset - Identifies which state sensor within a composite
+ * state sensor the event is being returned for
+ *  @param[out] event_state - The event state value from the state change that
+ * triggered the event message
+ *  @param[out] previous_event_state - The event state value for the state from
+ * which the present event state was entered
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'sensor_data'
+ */
+int decode_state_sensor_data(const uint8_t *sensor_data,
+			     size_t sensor_data_length, uint8_t *sensor_offset,
+			     uint8_t *event_state,
+			     uint8_t *previous_event_state);
+
+/** @brief Decode numericSensorState response data
+ *
+ *  @param[in] sensor_data - sensor_data for sensorEventClass =
+ * numericSensorState
+ *  @param[in] sensor_data_length - Length of sensor_data
+ *  @param[out] event_state - The eventState value from the state change that
+ * triggered the event message
+ *  @param[out] previous_event_state - The eventState value for the state from
+ * which the present state was entered
+ *  @param[out] sensor_data_size - The bit width and format of reading and
+ * threshold values that the sensor returns
+ *  @param[out] present_reading - The present value indicated by the sensor
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'sensor_data'
+ */
+int decode_numeric_sensor_data(const uint8_t *sensor_data,
+			       size_t sensor_data_length, uint8_t *event_state,
+			       uint8_t *previous_event_state,
+			       uint8_t *sensor_data_size,
+			       uint32_t *present_reading);
+
+/* GetNumericEffecterValue */
+
+/** @brief Create a PLDM request message for GetNumericEffecterValue
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] effecter_id - used to identify and access the effecter
+ *  @param[out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'msg.payload'
+ */
+int encode_get_numeric_effecter_value_req(uint8_t instance_id,
+					  uint16_t effecter_id,
+					  struct pldm_msg *msg);
+
+/** @brief Create a PLDM response message for GetNumericEffecterValue
+ *
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - Length of request message payload
+ *  @param[out] completion_code - PLDM completion code
+ *  @param[out] effecter_data_size - The bit width and format of the setting
+ *		value for the effecter.
+ *		value:{uint8,sint8,uint16,sint16,uint32,sint32}
+ *  @param[out] effecter_oper_state - The state of the effecter itself
+ *  @param[out] pending_value - The pending numeric value setting of the
+ *              effecter. The effecterDataSize field indicates the number of
+ *              bits used for this field
+ *  @param[out] present_value - The present numeric value setting of the
+ *              effecter. The effecterDataSize indicates the number of bits
+ *              used for this field
+ *  @return pldm_completion_codes
+ */
+int decode_get_numeric_effecter_value_resp(
+    const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
+    uint8_t *effecter_data_size, uint8_t *effecter_oper_state,
+    uint8_t *pending_value, uint8_t *present_value);
+
+/** @brief Decode pldmPDRRepositoryChgEvent response data
+ *
+ *  @param[in] event_data - eventData for pldmPDRRepositoryChgEvent
+ *  @param[in] event_data_size - Length of event_data
+ *  @param[out] event_data_format - This field indicates if the changedRecords
+ * are of PDR Types or PDR Record Handles
+ *  @param[out] number_of_change_records - The number of changeRecords following
+ * this field
+ *  @param[out] change_record_data_offset - Identifies where changeRecord data
+ * is located within event_data
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'event_data'
+ */
+int decode_pldm_pdr_repository_chg_event_data(
+    const uint8_t *event_data, size_t event_data_size,
+    uint8_t *event_data_format, uint8_t *number_of_change_records,
+    size_t *change_record_data_offset);
+
+/** @brief Encode PLDM PDR Repository Change eventData
+ *  @param[in] event_data_format - Format of this event data (e.g.
+ * FORMAT_IS_PDR_HANDLES)
+ *  @param[in] number_of_change_records - Number of changeRecords in this
+ * eventData
+ *  @param[in] event_data_operations - Array of eventDataOperations
+ *      (e.g. RECORDS_ADDED) for each changeRecord in this eventData. This array
+ * should contain number_of_change_records elements.
+ *  @param[in] numbers_of_change_entries - Array of numbers of changeEntrys
+ *      for each changeRecord in this eventData. This array should contain
+ *      number_of_change_records elements.
+ *  @param[in] change_entries - 2-dimensional array of arrays of changeEntrys,
+ *      one array per changeRecord in this eventData. The toplevel array should
+ *      contain number_of_change_records elements. Each subarray [i] should
+ *      contain numbers_of_change_entries[i] elements.
+ *  @param[in] event_data - The eventData will be encoded into this. This entire
+ *      structure must be max_change_records_size long. It must be large enough
+ *      to accomodate the data to be encoded. The caller is responsible for
+ *      allocating and deallocating it, including the variable-size
+ *      'event_data.change_records' field. If this parameter is NULL,
+ *      PLDM_SUCCESS will be returned and actual_change_records_size will be set
+ *      to reflect the required size of the structure.
+ *  @param[out] actual_change_records_size - The actual number of meaningful
+ *      encoded bytes in event_data. The caller can over-allocate memory and use
+ *      this output to determine the real size of the structure.
+ *  @param[in] max_change_records_size - The size of event_data in bytes. If the
+ *      encoded message would be larger than this value, an error is returned.
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ * 'event_data.change_records'
+ */
+int encode_pldm_pdr_repository_chg_event_data(
+    uint8_t event_data_format, uint8_t number_of_change_records,
+    const uint8_t *event_data_operations,
+    const uint8_t *numbers_of_change_entries,
+    const uint32_t *const *change_entries,
+    struct pldm_pdr_repository_chg_event_data *event_data,
+    size_t *actual_change_records_size, size_t max_change_records_size);
+
+/** @brief Encode event data for a PLDM Sensor Event
+ *
+ *  @param[out] event_data              The object to store the encoded event in
+ *  @param[in] event_data_size          Size of the allocation for event_data
+ *  @param[in] sensor_id                Sensor ID
+ *  @param[in] sensor_event_class       Sensor event class
+ *  @param[in] sensor_offset            Offset
+ *  @param[in] event_state              Event state
+ *  @param[in] previous_event_state     Previous event state
+ *  @param[out] actual_event_data_size  The real size in bytes of the event_data
+ *  @return int pldm_completion_codes   PLDM_SUCCESS/PLDM_ERROR_INVALID_LENGTH
+ *  @note If event_data is NULL, then *actual_event_data_size will be set to
+ *        reflect the size of the event data, and PLDM_SUCCESS will be returned.
+ *  @note The caller is responsible for allocating and deallocating the
+ *        event_data
+ */
+int encode_sensor_event_data(struct pldm_sensor_event_data *event_data,
+			     size_t event_data_size, uint16_t sensor_id,
+			     enum sensor_event_class_states sensor_event_class,
+			     uint8_t sensor_offset, uint8_t event_state,
+			     uint8_t previous_event_state,
+			     size_t *actual_event_data_size);
+
+/** @brief Decode PldmPDRRepositoryChangeRecord response data
+ *
+ *  @param[in] change_record_data - changeRecordData for
+ * pldmPDRRepositoryChgEvent
+ *  @param[in] change_record_data_size - Length of change_record_data
+ *  @param[out] event_data_operation - This field indicates the changeEntries
+ * operation types
+ *  @param[out] number_of_change_entries - The number of changeEntries following
+ * this field
+ *  @param[out] change_entry_data_offset - Identifies where changeEntries data
+ * is located within change_record_data
+ *  @return pldm_completion_codes
+ *  @note  Caller is responsible for memory alloc and dealloc of param
+ *         'change_record_data'
+ */
+int decode_pldm_pdr_repository_change_record_data(
+    const uint8_t *change_record_data, size_t change_record_data_size,
+    uint8_t *event_data_operation, uint8_t *number_of_change_entries,
+    size_t *change_entry_data_offset);
+
+/* GetSensorReading */
+
+/** @brief Encode GetSensorReading request data
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] sensor_id - A handle that is used to identify and access the
+ *         sensor
+ *  @param[in] rearm_event_state - true =  manually re-arm EventState after
+ *         responding to this request, false = no manual re-arm
+ *  @param[out] msg - Message will be written to this
+ *  @return pldm_completion_codes
+ *  @note	Caller is responsible for memory alloc and dealloc of param
+ * 		'msg.payload'
+ */
+int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id,
+				  bool8_t rearm_event_state,
+				  struct pldm_msg *msg);
+
+/** @brief Decode GetSensorReading response data
+ *
+ *  @param[in] msg - Request message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[out] completion_code - PLDM completion code
+ *  @param[out] sensor_data_size - The bit width and format of reading and
+ *         threshold values
+ *  @param[out] sensor_operational_state - The state of the sensor itself
+ *  @param[out] sensor_event_message_enable - value: { noEventGeneration,
+ *         eventsDisabled, eventsEnabled, opEventsOnlyEnabled,
+ *         stateEventsOnlyEnabled }
+ *  @param[out] present_state - The most recently assessed state value monitored
+ *         by the sensor
+ *  @param[out] previous_state - The state that the presentState was entered
+ *         from
+ *  @param[out] event_state - Indicates which threshold crossing assertion
+ *         events have been detected
+ *  @param[out] present_reading - The present value indicated by the sensor
+ *  @return pldm_completion_codes
+ */
+
+int decode_get_sensor_reading_resp(
+    const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
+    uint8_t *sensor_data_size, uint8_t *sensor_operational_state,
+    uint8_t *sensor_event_message_enable, uint8_t *present_state,
+    uint8_t *previous_state, uint8_t *event_state, uint8_t *present_reading);
+
+/** @brief Encode the SetEventReceiver request message
+ *
+ * @param[in] instance_id - Message's instance id
+ * @param[in] event_message_global_enable - This value is used to enable or
+ *        disable event message generation from the terminus value: {
+ *        disable, enableAsync, enablePolling, enableAsyncKeepAlive }
+ * @param[in] transport_protocol_type - This value is provided in the request
+ *        to help the responder verify that the content of the
+ *        eventReceiverAddressInfo field used in this request is correct for
+ *        the messaging protocol supported by the terminus.
+ * @param[in] event_receiver_address_info - this value is a medium and
+ *        protocol-specific address that the responder should use when
+ *        transmitting event messages using the indicated protocol
+ * @param[in] heartbeat_timer - Amount of time in seconds after each elapsing
+ *        of which the terminus shall emit a heartbeat event to the receiver
+ * @param[out] msg - Argument to capture the Message
+ * @return pldm_completion_codes
+ */
+int encode_set_event_receiver_req(uint8_t instance_id,
+				  uint8_t event_message_global_enable,
+				  uint8_t transport_protocol_type,
+				  uint8_t event_receiver_address_info,
+				  uint16_t heartbeat_timer,
+				  struct pldm_msg *msg);
+
+/** @brief Decode the SetEventReceiver response message
+ *
+ * @param[in] msg - Request message
+ * @param[in] payload_length - Length of response message payload
+ * @param[out] completion_code - PLDM completion code
+ * @return pldm_completion_codes
+ */
+int decode_set_event_receiver_resp(const struct pldm_msg *msg,
+				   size_t payload_length,
+				   uint8_t *completion_code);
+
+/** @brief Decode the SetEventReceiver request message
+ *
+ * @param[in] msg - Request message
+ * @param[in] payload_length - Length of request message payload
+ * @param[out] event_message_global_enable - This value is used to enable or
+ *        disable event message generation from the terminus value: {
+ *        disable, enableAsync, enablePolling, enableAsyncKeepAlive }
+ * @param[out] transport_protocol_type - This value is provided in the request
+ *        to help the responder verify that the content of the
+ *        eventReceiverAddressInfo field used in this request is correct for
+ *        the messaging protocol supported by the terminus.
+ * @param[out] event_receiver_address_info - This value is a medium and
+ *        protocol-specific address that the responder should use when
+ *        transmitting event messages using the indicated protocol
+ * @param[out] heartbeat_timer - Amount of time in seconds after each elapsing
+ *        of which the terminus shall emit a heartbeat event to the receiver
+ * @return pldm_completion_codes
+ */
+int decode_set_event_receiver_req(const struct pldm_msg *msg,
+				  size_t payload_length,
+				  uint8_t *event_message_global_enable,
+				  uint8_t *transport_protocol_type,
+				  uint8_t *event_receiver_address_info,
+				  uint16_t *heartbeat_timer);
+
+/** @brief Encode the SetEventReceiver response message
+ *
+ *  @param[in] instance_id - Message's instance id
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[out] msg - Argument to capture the Message
+ *  @return pldm_completion_codes
+ */
+int encode_set_event_receiver_resp(uint8_t instance_id, uint8_t completion_code,
+				   struct pldm_msg *msg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PLATFORM_H */
diff --git a/include/libpldm/pldm.h b/include/libpldm/pldm.h
new file mode 120000
index 0000000..7d352b9
--- /dev/null
+++ b/include/libpldm/pldm.h
@@ -0,0 +1 @@
+requester/pldm.h
\ No newline at end of file
diff --git a/include/libpldm/pldm_types.h b/include/libpldm/pldm_types.h
new file mode 100644
index 0000000..e48cb8c
--- /dev/null
+++ b/include/libpldm/pldm_types.h
@@ -0,0 +1,165 @@
+#ifndef PLDM_TYPES_H
+#define PLDM_TYPES_H
+
+#include <stdint.h>
+
+typedef union {
+	uint8_t byte;
+	struct {
+		uint8_t bit0 : 1;
+		uint8_t bit1 : 1;
+		uint8_t bit2 : 1;
+		uint8_t bit3 : 1;
+		uint8_t bit4 : 1;
+		uint8_t bit5 : 1;
+		uint8_t bit6 : 1;
+		uint8_t bit7 : 1;
+	} __attribute__((packed)) bits;
+} bitfield8_t;
+
+/** @struct pldm_version
+ *
+ *
+ */
+typedef struct pldm_version {
+	uint8_t alpha;
+	uint8_t update;
+	uint8_t minor;
+	uint8_t major;
+} __attribute__((packed)) ver32_t;
+
+typedef uint8_t bool8_t;
+
+typedef union {
+	uint16_t value;
+	struct {
+		uint8_t bit0 : 1;
+		uint8_t bit1 : 1;
+		uint8_t bit2 : 1;
+		uint8_t bit3 : 1;
+		uint8_t bit4 : 1;
+		uint8_t bit5 : 1;
+		uint8_t bit6 : 1;
+		uint8_t bit7 : 1;
+		uint8_t bit8 : 1;
+		uint8_t bit9 : 1;
+		uint8_t bit10 : 1;
+		uint8_t bit11 : 1;
+		uint8_t bit12 : 1;
+		uint8_t bit13 : 1;
+		uint8_t bit14 : 1;
+		uint8_t bit15 : 1;
+	} __attribute__((packed)) bits;
+} bitfield16_t;
+
+typedef union {
+	uint32_t value;
+	struct {
+		uint8_t bit0 : 1;
+		uint8_t bit1 : 1;
+		uint8_t bit2 : 1;
+		uint8_t bit3 : 1;
+		uint8_t bit4 : 1;
+		uint8_t bit5 : 1;
+		uint8_t bit6 : 1;
+		uint8_t bit7 : 1;
+		uint8_t bit8 : 1;
+		uint8_t bit9 : 1;
+		uint8_t bit10 : 1;
+		uint8_t bit11 : 1;
+		uint8_t bit12 : 1;
+		uint8_t bit13 : 1;
+		uint8_t bit14 : 1;
+		uint8_t bit15 : 1;
+		uint8_t bit16 : 1;
+		uint8_t bit17 : 1;
+		uint8_t bit18 : 1;
+		uint8_t bit19 : 1;
+		uint8_t bit20 : 1;
+		uint8_t bit21 : 1;
+		uint8_t bit22 : 1;
+		uint8_t bit23 : 1;
+		uint8_t bit24 : 1;
+		uint8_t bit25 : 1;
+		uint8_t bit26 : 1;
+		uint8_t bit27 : 1;
+		uint8_t bit28 : 1;
+		uint8_t bit29 : 1;
+		uint8_t bit30 : 1;
+		uint8_t bit31 : 1;
+	} __attribute__((packed)) bits;
+} bitfield32_t;
+
+typedef union {
+	uint64_t value;
+	struct {
+		uint8_t bit0 : 1;
+		uint8_t bit1 : 1;
+		uint8_t bit2 : 1;
+		uint8_t bit3 : 1;
+		uint8_t bit4 : 1;
+		uint8_t bit5 : 1;
+		uint8_t bit6 : 1;
+		uint8_t bit7 : 1;
+		uint8_t bit8 : 1;
+		uint8_t bit9 : 1;
+		uint8_t bit10 : 1;
+		uint8_t bit11 : 1;
+		uint8_t bit12 : 1;
+		uint8_t bit13 : 1;
+		uint8_t bit14 : 1;
+		uint8_t bit15 : 1;
+		uint8_t bit16 : 1;
+		uint8_t bit17 : 1;
+		uint8_t bit18 : 1;
+		uint8_t bit19 : 1;
+		uint8_t bit20 : 1;
+		uint8_t bit21 : 1;
+		uint8_t bit22 : 1;
+		uint8_t bit23 : 1;
+		uint8_t bit24 : 1;
+		uint8_t bit25 : 1;
+		uint8_t bit26 : 1;
+		uint8_t bit27 : 1;
+		uint8_t bit28 : 1;
+		uint8_t bit29 : 1;
+		uint8_t bit30 : 1;
+		uint8_t bit31 : 1;
+		uint8_t bit32 : 1;
+		uint8_t bit33 : 1;
+		uint8_t bit34 : 1;
+		uint8_t bit35 : 1;
+		uint8_t bit36 : 1;
+		uint8_t bit37 : 1;
+		uint8_t bit38 : 1;
+		uint8_t bit39 : 1;
+		uint8_t bit40 : 1;
+		uint8_t bit41 : 1;
+		uint8_t bit42 : 1;
+		uint8_t bit43 : 1;
+		uint8_t bit44 : 1;
+		uint8_t bit45 : 1;
+		uint8_t bit46 : 1;
+		uint8_t bit47 : 1;
+		uint8_t bit48 : 1;
+		uint8_t bit49 : 1;
+		uint8_t bit50 : 1;
+		uint8_t bit51 : 1;
+		uint8_t bit52 : 1;
+		uint8_t bit53 : 1;
+		uint8_t bit54 : 1;
+		uint8_t bit55 : 1;
+		uint8_t bit56 : 1;
+		uint8_t bit57 : 1;
+		uint8_t bit58 : 1;
+		uint8_t bit59 : 1;
+		uint8_t bit60 : 1;
+		uint8_t bit61 : 1;
+		uint8_t bit62 : 1;
+		uint8_t bit63 : 1;
+	} __attribute__((packed)) bits;
+} bitfield64_t;
+
+typedef float real32_t;
+
+#endif /* PLDM_TYPES_H */
diff --git a/include/libpldm/requester/pldm.h b/include/libpldm/requester/pldm.h
new file mode 100644
index 0000000..9c5c71e
--- /dev/null
+++ b/include/libpldm/requester/pldm.h
@@ -0,0 +1,113 @@
+#ifndef MCTP_H
+#define MCTP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+typedef uint8_t mctp_eid_t;
+
+typedef enum pldm_requester_error_codes {
+	PLDM_REQUESTER_SUCCESS = 0,
+	PLDM_REQUESTER_OPEN_FAIL = -1,
+	PLDM_REQUESTER_NOT_PLDM_MSG = -2,
+	PLDM_REQUESTER_NOT_RESP_MSG = -3,
+	PLDM_REQUESTER_NOT_REQ_MSG = -4,
+	PLDM_REQUESTER_RESP_MSG_TOO_SMALL = -5,
+	PLDM_REQUESTER_INSTANCE_ID_MISMATCH = -6,
+	PLDM_REQUESTER_SEND_FAIL = -7,
+	PLDM_REQUESTER_RECV_FAIL = -8,
+	PLDM_REQUESTER_INVALID_RECV_LEN = -9,
+} pldm_requester_rc_t;
+
+/**
+ * @brief Connect to the MCTP socket and provide an fd to it. The fd can be
+ *        used to pass as input to other APIs below, or can be polled.
+ *
+ * @return fd on success, pldm_requester_rc_t on error (errno may be set)
+ */
+pldm_requester_rc_t pldm_open();
+
+/**
+ * @brief Send a PLDM request message. Wait for corresponding response message,
+ *        which once received, is returned to the caller.
+ *
+ * @param[in] eid - destination MCTP eid
+ * @param[in] mctp_fd - MCTP socket fd
+ * @param[in] pldm_req_msg - caller owned pointer to PLDM request msg
+ * @param[in] req_msg_len - size of PLDM request msg
+ * @param[out] pldm_resp_msg - *pldm_resp_msg will point to PLDM response msg,
+ *             this function allocates memory, caller to free(*pldm_resp_msg) on
+ *             success.
+ * @param[out] resp_msg_len - caller owned pointer that will be made point to
+ *             the size of the PLDM response msg.
+ *
+ * @return pldm_requester_rc_t (errno may be set)
+ */
+pldm_requester_rc_t pldm_send_recv(mctp_eid_t eid, int mctp_fd,
+				   const uint8_t *pldm_req_msg,
+				   size_t req_msg_len, uint8_t **pldm_resp_msg,
+				   size_t *resp_msg_len);
+
+/**
+ * @brief Send a PLDM request message, don't wait for response. Essentially an
+ *        async API. A user of this would typically have added the MCTP fd to an
+ *        event loop for polling. Once there's data available, the user would
+ *        invoke pldm_recv().
+ *
+ * @param[in] eid - destination MCTP eid
+ * @param[in] mctp_fd - MCTP socket fd
+ * @param[in] pldm_req_msg - caller owned pointer to PLDM request msg
+ * @param[in] req_msg_len - size of PLDM request msg
+ *
+ * @return pldm_requester_rc_t (errno may be set)
+ */
+pldm_requester_rc_t pldm_send(mctp_eid_t eid, int mctp_fd,
+			      const uint8_t *pldm_req_msg, size_t req_msg_len);
+
+/**
+ * @brief Read MCTP socket. If there's data available, return success only if
+ *        data is a PLDM response message that matches eid and instance_id.
+ *
+ * @param[in] eid - destination MCTP eid
+ * @param[in] mctp_fd - MCTP socket fd
+ * @param[in] instance_id - PLDM instance id of previously sent PLDM request msg
+ * @param[out] pldm_resp_msg - *pldm_resp_msg will point to PLDM response msg,
+ *             this function allocates memory, caller to free(*pldm_resp_msg) on
+ *             success.
+ * @param[out] resp_msg_len - caller owned pointer that will be made point to
+ *             the size of the PLDM response msg.
+ *
+ * @return pldm_requester_rc_t (errno may be set). failure is returned even
+ *         when data was read, but didn't match eid or instance_id.
+ */
+pldm_requester_rc_t pldm_recv(mctp_eid_t eid, int mctp_fd, uint8_t instance_id,
+			      uint8_t **pldm_resp_msg, size_t *resp_msg_len);
+
+/**
+ * @brief Read MCTP socket. If there's data available, return success only if
+ *        data is a PLDM response message.
+ *
+ * @param[in] eid - destination MCTP eid
+ * @param[in] mctp_fd - MCTP socket fd
+ * @param[out] pldm_resp_msg - *pldm_resp_msg will point to PLDM response msg,
+ *             this function allocates memory, caller to free(*pldm_resp_msg) on
+ *             success.
+ * @param[out] resp_msg_len - caller owned pointer that will be made point to
+ *             the size of the PLDM response msg.
+ *
+ * @return pldm_requester_rc_t (errno may be set). failure is returned even
+ *         when data was read, but wasn't a PLDM response message
+ */
+pldm_requester_rc_t pldm_recv_any(mctp_eid_t eid, int mctp_fd,
+				  uint8_t **pldm_resp_msg,
+				  size_t *resp_msg_len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MCTP_H */
diff --git a/include/libpldm/state_set.h b/include/libpldm/state_set.h
new file mode 100644
index 0000000..23fd91c
--- /dev/null
+++ b/include/libpldm/state_set.h
@@ -0,0 +1,236 @@
+#ifndef STATE_SET_H
+#define STATE_SET_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief PLDM State Set IDs in DSP0249_1.1.0 specification
+ */
+enum pldm_state_set_ids {
+
+	/* Table 1 - General State Sets */
+	PLDM_STATE_SET_HEALTH_STATE = 1,
+	PLDM_STATE_SET_AVAILABILITY = 2,
+	PLDM_STATE_SET_PREDICTIVE_CONDITION = 3,
+	PLDM_STATE_SET_REDUNDANCY_STATUS = 4,
+	PLDM_STATE_SET_HEALTH_REDUNDANCY_TREND = 5,
+	PLDM_STATE_SET_GROUP_RESOURCE_LEVEL = 6,
+	PLDM_STATE_SET_REDUNDANCY_ENTITY_ROLE = 7,
+	PLDM_STATE_SET_OPERATIONAL_STATUS = 8,
+	PLDM_STATE_SET_OPERATIONAL_STRESS_STATUS = 9,
+	PLDM_STATE_SET_OPERATIONAL_FAULT_STATUS = 10,
+	PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS = 11,
+	PLDM_STATE_SET_OPERATIONAL_CONNECTION_STATUS = 12,
+	PLDM_STATE_SET_PRESENCE = 13,
+	PLDM_STATE_SET_PERFORMANCE = 14,
+	PLDM_STATE_SET_CONFIGURATION_STATE = 15,
+	PLDM_STATE_SET_CHANGED_CONFIGURATION = 16,
+	PLDM_STATE_SET_IDENTIFY_STATE = 17,
+	PLDM_STATE_SET_VERSION = 18,
+	PLDM_STATE_SET_ALARM_STATE = 19,
+	PLDM_STATE_SET_DEVICE_INITIALIZATION = 20,
+	PLDM_STATE_SET_THERMAL_TRIP = 21,
+
+	/* Table 2 - Communication State Sets */
+	PLDM_STATE_SET_HEARTBEAT = 32,
+	PLDM_STATE_SET_LINK_STATE = 33,
+
+	/* Table 3 - General Sensor State Sets */
+	PLDM_STATE_SET_SMOKE_STATE = 64,
+	PLDM_STATE_SET_HUMIDITY_STATE = 65,
+	PLDM_STATE_SET_DOOR_STATE = 66,
+	PLDM_STATE_SET_SWITCH_STATE = 67,
+
+	/* Table 4 - Security-Related State Sets */
+	PLDM_STATE_SET_LOCK_STATE = 96,
+	PLDM_STATE_SET_PHYSICAL_SECURITY = 97,
+	PLDM_STATE_SET_DOCK_AUTHORIZATION = 98,
+	PLDM_STATE_SET_HW_SECURITY = 99,
+	PLDM_STATE_SET_PHYSICAL_COMM_CONNECTION = 100,
+	PLDM_STATE_SET_COMM_LEASH_STATUS = 101,
+	PLDM_STATE_SET_FOREIGN_NW_DETECTION_STATUS = 102,
+	PLDM_STATE_SET_PASSWORD_PROTECTED_ACCESS_SECURITY = 103,
+	PLDM_STATE_SET_SECURITY_ACCESS_PRIVILEGE_LEVEL = 104,
+	PLDM_STATE_SET_SESSION_AUDIT = 105,
+
+	/* Table 5 - Software-Related State Sets */
+	PLDM_STATE_SET_SW_TERMINATION_STATUS = 129,
+
+	/* Table 6 - Redundant Storage Media (RAID) State Sets */
+	PLDM_STATE_SET_STORAGE_MEDIA_ACTIVITY = 160,
+
+	/* Table 7 - Boot-Related State Sets */
+	PLDM_STATE_SET_BOOT_RESTART_CAUSE = 192,
+	PLDM_STATE_SET_BOOT_RESTART_REQUEST = 193,
+	PLDM_STATE_SET_ENTITY_BOOT_STATUS = 194,
+	PLDM_STATE_SET_BOOT_ERROR_STATUS = 195,
+	PLDM_STATE_SET_BOOT_PROGRESS = 196,
+	PLDM_STATE_SET_SYS_FIRMWARE_HANG = 197,
+	PLDM_STATE_SET_POST_ERRORS = 198,
+
+	/* Table 8 - Monitored System-Related State Sets */
+	PLDM_STATE_SET_LOG_FILL_STATUS = 225,
+	PLDM_STATE_SET_LOG_FILTER_STATUS = 226,
+	PLDM_STATE_SET_LOG_TIMESTAMP_CHANGE = 227,
+	PLDM_STATE_SET_INTERRUPT_REQUESTED = 228,
+	PLDM_STATE_SET_INTERRUPT_RECEIVED = 229,
+	PLDM_STATE_SET_DIAGNOSTIC_INTERRUPT_REQUESTED = 230,
+	PLDM_STATE_SET_DIAGNOSTIC_INTERRUPT_RECEIVED = 231,
+	PLDM_STATE_SET_IO_CHANNEL_CHECK_NMI_REQUESTED = 232,
+	PLDM_STATE_SET_IO_CHANNEL_CHECK_NMI_RECEIVED = 233,
+	PLDM_STATE_SET_FATAL_NMI_REQUESTED = 234,
+	PLDM_STATE_SET_FATAL_NMI_RECEIVED = 235,
+	PLDM_STATE_SET_SOFTWARE_NMI_REQUESTED = 236,
+	PLDM_STATE_SET_SOFTWARE_NMI_RECEIVED = 237,
+	PLDM_STATE_SET_SMI_REQUESTED = 238,
+	PLDM_STATE_SET_SMI_RECEIVED = 238,
+	PLDM_STATE_SET_PCI_PERR_REQUESTED = 239,
+	PLDM_STATE_SET_PCI_PERR_RECEIVED = 240,
+	PLDM_STATE_SET_PCI_SERR_REQUESTED = 241,
+	PLDM_STATE_SET_PCI_SERR_RECEIVED = 242,
+	PLDM_STATE_SET_BUS_ERROR_STATUS = 243,
+	PLDM_STATE_SET_WATCHDOG_STATUS = 244,
+
+	/* Table 9 - Power-Related State Sets */
+	PLDM_STATE_SET_POWER_SUPPLY_STATE = 256,
+	PLDM_STATE_SET_DEVICE_POWER_STATE = 257,
+	PLDM_STATE_SET_ACPI_POWER_STATE = 258,
+	PLDM_STATE_SET_BACKUP_POWER_SOURCE = 259,
+	PLDM_STATE_SET_SYSTEM_POWER_STATE = 260,
+	PLDM_STATE_SET_BATTERY_ACTIVITY = 261,
+	PLDM_STATE_SET_BATTERY_STATE = 262,
+
+	/* Table 10 - Processor-Related State Sets */
+	PLDM_STATE_SET_PROC_POWER_STATE = 288,
+	PLDM_STATE_SET_POWER_PERFORMANCE_STATE = 289,
+	PLDM_STATE_SET_PROC_ERROR_STATUS = 290,
+	PLDM_STATE_SET_BIST_FAILURE_STATUS = 291,
+	PLDM_STATE_SET_IBIST_FAILURE_STATUS = 292,
+	PLDM_STATE_SET_PROC_HANG_IN_POST = 293,
+	PLDM_STATE_SET_PROC_STARTUP_FAILURE = 294,
+	PLDM_STATE_SET_UNCORRECTABLE_CPU_ERROR = 295,
+	PLDM_STATE_SET_MACHINE_CHECK_ERROR = 296,
+	PLDM_STATE_SET_CORRECTED_MACHINE_CHECK = 297,
+
+	/* Table 11 - Memory-Related State Sets */
+	PLDM_STATE_SET_CACHE_STATUS = 320,
+	PLDM_STATE_SET_MEMORY_ERROR_STATUS = 321,
+	PLDM_STATE_SET_REDUNDANT_MEMORY_ACTIVITY_STATUS = 322,
+
+	/* Table 12 - Storage Device State Sets */
+	PLDM_STATE_SET_ERROR_DETECTION_STATUS = 330,
+	PLDM_STATE_SET_STUCK_BIT_STATUS = 331,
+	PLDM_STATE_SET_SCRUB_STATUS = 332,
+
+	/* Table 13 - Slot/Module State Sets */
+	PLDM_STATE_SET_SLOT_OCCUPANCY = 352,
+	PLDM_STATE_SET_SLOT_STATE = 353,
+};
+
+/* @brief List of states for the Health State state set (ID 1).
+ */
+enum pldm_state_set_health_state_values {
+	PLDM_STATE_SET_HEALTH_STATE_NORMAL = 1,
+	PLDM_STATE_SET_HEALTH_STATE_NON_CRITICAL = 2,
+	PLDM_STATE_SET_HEALTH_STATE_CRITICAL = 3,
+	PLDM_STATE_SET_HEALTH_STATE_FATAL = 4,
+	PLDM_STATE_SET_HEALTH_STATE_UPPER_NON_CRITICAL = 5,
+	PLDM_STATE_SET_HEALTH_STATE_LOWER_NON_CRITICAL = 6,
+	PLDM_STATE_SET_HEALTH_STATE_UPPER_CRITICAL = 7,
+	PLDM_STATE_SET_HEALTH_STATE_LOWER_CRITICAL = 8,
+	PLDM_STATE_SET_HEALTH_STATE_UPPER_FATAL = 9,
+	PLDM_STATE_SET_HEALTH_STATE_LOWER_FATAL = 10,
+};
+
+/* @brief List of states for the State Set Availability (ID 2),
+ */
+enum pldm_state_set_availability_values {
+	PLDM_STATE_SET_AVAILABILITY_REBOOTING = 8
+};
+
+/* @brief List of states for the Operational Fault status (ID 10).
+ */
+enum pldm_state_set_operational_fault_status_values {
+	PLDM_STATE_SET_OPERATIONAL_FAULT_STATUS_NORMAL = 1,
+	PLDM_STATE_SET_OPERATIONAL_FAULT_STATUS_STRESSED = 2,
+};
+
+/* @brief List of states for the Operational Running Status state set (ID 11).
+ */
+enum pldm_state_set_operational_running_status_values {
+	PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_STARTING = 1,
+	PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_STOPPING = 2,
+	PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_STOPPED = 3,
+	PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_IN_SERVICE = 4,
+	PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_ABORTED = 5,
+	PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_DORMANT = 6
+};
+
+/* @brief List of states for the Set Identify state (ID 17).
+ */
+enum pldm_state_set_identify_state_values {
+	PLDM_STATE_SET_IDENTIFY_STATE_UNASSERTED = 1,
+	PLDM_STATE_SET_IDENTIFY_STATE_ASSERTED = 2,
+};
+
+/* @brief List of states for the Set Thermal Trip state set (ID 21).
+ */
+enum pldm_state_set_thermal_trip_values {
+	PLDM_STATE_SET_THERMAL_TRIP_STATUS_NORMAL = 1,
+	PLDM_STATE_SET_THERMAL_TRIP_STATUS_THERMAL_TRIP = 2,
+};
+
+/* @brief List of states for the Software-related state set (ID 129).
+ */
+enum pldm_software_termination_status_values {
+	PLDM_SW_TERM_NORMAL = 1,
+	PLDM_SW_TERM_SOFTWARE_TERMINATION_DETECTED = 2,
+	PLDM_SW_TERM_CRITICAL_STOP_DURING_LOAD_INITIALIZATION = 3,
+	PLDM_SW_TERM_RUN_TIME_CRITICAL_STOP = 4,
+	PLDM_SW_TERM_GRACEFUL_SHUTDOWN_REQUESTED = 5,
+	PLDM_SW_TERM_GRACEFUL_RESTART_REQUESTED = 6,
+	PLDM_SW_TERM_GRACEFUL_SHUTDOWN = 7,
+	PLDM_SW_TERM_TERMINATION_REQUEST_FAILED = 8,
+};
+
+/* @brief List of states for the Boot Restart Cause state set (ID 192).
+ */
+enum pldm_state_set_boot_restart_cause_values {
+	PLDM_STATE_SET_BOOT_RESTART_CAUSE_POWERED_UP = 1,
+	PLDM_STATE_SET_BOOT_RESTART_CAUSE_HARD_RESET = 2,
+	PLDM_STATE_SET_BOOT_RESTART_CAUSE_WARM_RESET = 3,
+	PLDM_STATE_SET_BOOT_RESTART_CAUSE_MANUAL_HARD_RESET = 4,
+	PLDM_STATE_SET_BOOT_RESTART_CAUSE_MANUAL_WARM_RESET = 5,
+	PLDM_STATE_SET_BOOT_RESTART_CAUSE_SYSTEM_RESTART = 6,
+	PLDM_STATE_SET_BOOT_RESTART_CAUSE_WATCHDOG_TIMEOUT = 7
+};
+
+/* @brief List of states for the Boot Progress state set (ID 196).
+ */
+enum pldm_state_set_boot_progress_state_values {
+	PLDM_STATE_SET_BOOT_PROG_STATE_NOT_ACTIVE = 1,
+	PLDM_STATE_SET_BOOT_PROG_STATE_COMPLETED = 2,
+	PLDM_STATE_SET_BOOT_PROG_STATE_MEM_INITIALIZATION = 3,
+	PLDM_STATE_SET_BOOT_PROG_STATE_SEC_PROC_INITIALIZATION = 5,
+	PLDM_STATE_SET_BOOT_PROG_STATE_PCI_RESORUCE_CONFIG = 9,
+	PLDM_STATE_SET_BOOT_PROG_STATE_STARTING_OP_SYS = 21,
+	PLDM_STATE_SET_BOOT_PROG_STATE_BASE_BOARD_INITIALIZATION = 22,
+	PLDM_STATE_SET_BOOT_PROG_STATE_PRIMARY_PROC_INITIALIZATION = 26,
+};
+
+/* @brief List of states for the System Power State set (ID 260).
+ */
+enum pldm_state_set_system_power_state_values {
+	PLDM_STATE_SET_SYS_POWER_STATE_OFF_SOFT_GRACEFUL = 9
+};
+
+/* OEM ranges */
+#define PLDM_OEM_STATE_SET_ID_START 32768
+#define PLDM_OEM_STATE_SET_ID_END 65535
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STATE_SET_H */
diff --git a/include/libpldm/states.h b/include/libpldm/states.h
new file mode 100644
index 0000000..a89648d
--- /dev/null
+++ b/include/libpldm/states.h
@@ -0,0 +1,27 @@
+#ifndef STATES_H
+#define STATES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "pldm_types.h"
+
+/** @brief PLDM enums for the boot progress state set
+ */
+enum pldm_boot_progress_states {
+	PLDM_BOOT_NOT_ACTIVE = 1,
+	PLDM_BOOT_COMPLETED = 2,
+};
+
+/** @brief PLDM enums for system power states
+ */
+enum pldm_system_power_states {
+	PLDM_OFF_SOFT_GRACEFUL = 9,
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STATES_H */
diff --git a/include/libpldm/utils.h b/include/libpldm/utils.h
new file mode 100644
index 0000000..35b039b
--- /dev/null
+++ b/include/libpldm/utils.h
@@ -0,0 +1,108 @@
+#ifndef UTILS_H__
+#define UTILS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "pldm_types.h"
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+/** @struct variable_field
+ *
+ *  Structure representing variable field in the pldm message
+ */
+struct variable_field {
+	const uint8_t *ptr;
+	size_t length;
+};
+
+/** @brief Compute Crc8(same as the one used by SMBUS)
+ *
+ *  @param[in] data - Pointer to the target data
+ *  @param[in] size - Size of the data
+ *  @return The checksum
+ */
+uint8_t crc8(const void *data, size_t size);
+
+/** @brief Compute Crc32(same as the one used by IEEE802.3)
+ *
+ *  @param[in] data - Pointer to the target data
+ *  @param[in] size - Size of the data
+ *  @return The checksum
+ */
+uint32_t crc32(const void *data, size_t size);
+
+/** @brief Convert ver32_t to string
+ *  @param[in] version - Pointer to ver32_t
+ *  @param[out] buffer - Pointer to the buffer
+ *  @param[in] buffer_size - Size of the buffer
+ *  @return The number of characters(excluding the null byte) or negative if
+ * error is encountered
+ */
+int ver2str(const ver32_t *version, char *buffer, size_t buffer_size);
+
+/** @brief Convert bcd number(uint8_t) to decimal
+ *  @param[in] bcd - bcd number
+ *  @return the decimal number
+ */
+uint8_t bcd2dec8(uint8_t bcd);
+
+/** @brief Convert decimal number(uint8_t) to bcd
+ *  @param[in] dec - decimal number
+ *  @return the bcd number
+ */
+uint8_t dec2bcd8(uint8_t dec);
+
+/** @brief Convert bcd number(uint16_t) to decimal
+ *  @param[in] bcd - bcd number
+ *  @return the decimal number
+ */
+uint16_t bcd2dec16(uint16_t bcd);
+
+/** @brief Convert decimal number(uint16_t) to bcd
+ *  @param[in] dec - decimal number
+ *  @return the bcd number
+ */
+uint16_t dec2bcd16(uint16_t dec);
+
+/** @brief Convert bcd number(uint32_t) to decimal
+ *  @param[in] bcd - bcd number
+ *  @return the decimal number
+ */
+uint32_t bcd2dec32(uint32_t bcd);
+
+/** @brief Convert decimal number(uint32_t) to bcd
+ *  @param[in] dec - decimal number
+ *  @return the bcd number
+ */
+uint32_t dec2bcd32(uint32_t dec);
+
+/** @brief Check whether the input time is legal
+ *
+ *  @param[in] seconds. Value range 0~59
+ *  @param[in] minutes. Value range 0~59
+ *  @param[in] hours. Value range 0~23
+ *  @param[in] day. Value range 1~31
+ *  @param[in] month. Value range 1~12
+ *  @param[in] year. Value range 1970~
+ *  @return true if time is legal,false if time is illegal
+ */
+bool is_time_legal(uint8_t seconds, uint8_t minutes, uint8_t hours, uint8_t day,
+		   uint8_t month, uint16_t year);
+
+/** @brief Check whether transfer flag is valid
+ *
+ *  @param[in] transfer_flag - TransferFlag
+ *
+ *  @return true if transfer flag is valid, false if not
+ */
+bool is_transfer_flag_valid(uint8_t transfer_flag);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif