oem-ibm: implement WriteFileByTypeFromMemory handler

This commit implements a framework for handling oem file types
received to/from host. Along with that it also implements the responder
for oem command WriteFileByTypeFromMemory and processes PELs received
from the host firmware.

Change-Id: Ice866aed0343b90769013c4be31a0c730f6e6bcd
Signed-off-by: Sampa Misra <sampmisr@in.ibm.com>
diff --git a/oem/ibm/libpldmresponder/file_io_by_type.cpp b/oem/ibm/libpldmresponder/file_io_by_type.cpp
new file mode 100644
index 0000000..d8a40a5
--- /dev/null
+++ b/oem/ibm/libpldmresponder/file_io_by_type.cpp
@@ -0,0 +1,73 @@
+#include "config.h"
+
+#include "file_io_by_type.hpp"
+
+#include "file_io_type_pel.hpp"
+#include "libpldmresponder/utils.hpp"
+#include "xyz/openbmc_project/Common/error.hpp"
+
+#include <stdint.h>
+#include <unistd.h>
+
+#include <exception>
+#include <filesystem>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
+#include <vector>
+#include <xyz/openbmc_project/Logging/Entry/server.hpp>
+
+#include "libpldm/base.h"
+#include "oem/ibm/libpldm/file_io.h"
+
+namespace pldm
+{
+namespace responder
+{
+
+using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+
+int FileHandler::transferFileData(const fs::path& path, bool upstream,
+                                  uint32_t offset, uint32_t length,
+                                  uint64_t address)
+{
+    dma::DMA xdmaInterface;
+
+    while (length > dma::maxSize)
+    {
+        auto rc = xdmaInterface.transferDataHost(path, offset, dma::maxSize,
+                                                 address, upstream);
+        if (rc < 0)
+        {
+            return PLDM_ERROR;
+        }
+        offset += dma::maxSize;
+        length -= dma::maxSize;
+        address += dma::maxSize;
+    }
+    auto rc =
+        xdmaInterface.transferDataHost(path, offset, length, address, upstream);
+    return rc < 0 ? PLDM_ERROR : PLDM_SUCCESS;
+}
+
+std::unique_ptr<FileHandler> getHandlerByType(uint16_t fileType,
+                                              uint32_t fileHandle)
+{
+    switch (fileType)
+    {
+        case PLDM_FILE_TYPE_PEL:
+        {
+            return std::make_unique<PelHandler>(fileHandle);
+            break;
+        }
+        default:
+        {
+            elog<InternalFailure>();
+            break;
+        }
+    }
+    return nullptr;
+}
+
+} // namespace responder
+} // namespace pldm