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_type_pel.cpp b/oem/ibm/libpldmresponder/file_io_type_pel.cpp
new file mode 100644
index 0000000..400d336
--- /dev/null
+++ b/oem/ibm/libpldmresponder/file_io_type_pel.cpp
@@ -0,0 +1,85 @@
+#include "config.h"
+
+#include "file_io_type_pel.hpp"
+
+#include "libpldmresponder/utils.hpp"
+#include "xyz/openbmc_project/Common/error.hpp"
+
+#include <stdint.h>
+#include <systemd/sd-bus.h>
+#include <unistd.h>
+
+#include <exception>
+#include <filesystem>
+#include <sdbusplus/server.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;
+
+int PelHandler::writeFromMemory(uint32_t offset, uint32_t length,
+ uint64_t address)
+{
+ fs::create_directories(PEL_TEMP_DIR);
+
+ auto timeMs =
+ std::chrono::duration_cast<std::chrono::milliseconds>(
+ std::chrono::high_resolution_clock::now().time_since_epoch())
+ .count();
+ std::string fileName(PEL_TEMP_DIR);
+ fileName += "/pel." + std::to_string(timeMs);
+ fs::path path(std::move(fileName));
+
+ auto rc = transferFileData(path, false, offset, length, address);
+ if (rc == PLDM_SUCCESS)
+ {
+ rc = storePel(path.string());
+ }
+ fs::remove(path);
+ return rc;
+}
+
+int PelHandler::storePel(std::string&& pelFileName)
+{
+ static constexpr auto logObjPath = "/xyz/openbmc_project/logging";
+ static constexpr auto logInterface = "xyz.openbmc_project.Logging.Create";
+
+ static sdbusplus::bus::bus bus = sdbusplus::bus::new_default();
+
+ try
+ {
+ auto service = getService(bus, logObjPath, logInterface);
+ using namespace sdbusplus::xyz::openbmc_project::Logging::server;
+ std::map<std::string, std::string> addlData{};
+ addlData.emplace("RAWPEL", std::move(pelFileName));
+ auto severity =
+ sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage(
+ sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level::
+ Error);
+
+ auto method = bus.new_method_call(service.c_str(), logObjPath,
+ logInterface, "Create");
+ method.append("xyz.openbmc_project.Host.Error.Event", severity,
+ addlData);
+ bus.call_noreply(method);
+ }
+ catch (const std::exception& e)
+ {
+ log<level::ERR>("failed to make a d-bus call to PEL daemon",
+ entry("ERROR=%s", e.what()));
+ return PLDM_ERROR;
+ }
+
+ return PLDM_SUCCESS;
+}
+
+} // namespace responder
+} // namespace pldm