oem-ibm : Add new filetype & logic for handling Progress Codes

- The intent behind this commit , is to add a new file type
  for handling IBM Progress Codes.

- The Progress Codes are typically in bytes(<200 bytes), which
  is why the host does an inband write rather than using the DMA.

- Once the Progress Code structure is received, pldm would peek into
  the buffer to find out the Primary Code which is typically an 8 byte
  Hex number (starts at a standard offset 40).

- Once , we get the Primary Code  then we pack it into a structure and
  set the dbus property which is hosted by the snoopd daemon.

Tested By :

1. PLDM Tool

./pldmtool raw --data 0x80 0x3F 0xC 0x0A 0x00 0x00 0x00 0x00 0x00 0x07
0x00 0x00 0x00 0x48 0x00 0x00 0x00 0x02 0x00 0x00 0x01 0x00 0x00 0x00
0x48 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x53 0x54 0x41 0x4e 0x44 0x42 0x59 0x20 0x20
0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20
0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20 0x20
Request Message:
08 01 80 3f 0c 0a 00 00 00 00 00 07 00 00 00 48 00 00 00 02 00 00 01 00
00 00 48 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 53 54 41 4e 44 42 59 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
Progress SRC Structure : 02 00 00 01 00 00 00 48 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
53 54 41 4e 44 42 59 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20
Primary Progress Code in Hex : 5354414e44425920

The Ascii Value of 5354414e44425920 is STANDBY(Host reaching standby)

Signed-off-by: Manojkiran Eda <manojkiran.eda@gmail.com>
Change-Id: I1c8529070ed0718e7770bae99964445e5b14bd65
diff --git a/libpldmresponder/meson.build b/libpldmresponder/meson.build
index d90161d..4377e39 100644
--- a/libpldmresponder/meson.build
+++ b/libpldmresponder/meson.build
@@ -38,6 +38,7 @@
     '../oem/ibm/libpldmresponder/oem_ibm_handler.cpp',
     '../oem/ibm/libpldmresponder/inband_code_update.cpp',
     '../oem/ibm/requester/dbus_to_file_handler.cpp',
+    '../oem/ibm/libpldmresponder/file_io_type_progress_src.cpp',
   ]
 endif
 
diff --git a/oem/ibm/libpldm/file_io.h b/oem/ibm/libpldm/file_io.h
index a501c93..07db4ed 100644
--- a/oem/ibm/libpldm/file_io.h
+++ b/oem/ibm/libpldm/file_io.h
@@ -56,6 +56,7 @@
 	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,
 };
 
 #define PLDM_RW_FILE_MEM_REQ_BYTES 20
diff --git a/oem/ibm/libpldmresponder/file_io_by_type.cpp b/oem/ibm/libpldmresponder/file_io_by_type.cpp
index fd0144e..9bd5e74 100644
--- a/oem/ibm/libpldmresponder/file_io_by_type.cpp
+++ b/oem/ibm/libpldmresponder/file_io_by_type.cpp
@@ -10,6 +10,7 @@
 #include "file_io_type_dump.hpp"
 #include "file_io_type_lid.hpp"
 #include "file_io_type_pel.hpp"
+#include "file_io_type_progress_src.hpp"
 #include "xyz/openbmc_project/Common/error.hpp"
 
 #include <stdint.h>
@@ -156,6 +157,10 @@
         {
             return std::make_unique<CertHandler>(fileHandle, fileType);
         }
+        case PLDM_FILE_TYPE_PROGRESS_SRC:
+        {
+            return std::make_unique<ProgressCodeHandler>(fileHandle);
+        }
         default:
         {
             throw InternalFailure();
diff --git a/oem/ibm/libpldmresponder/file_io_type_progress_src.cpp b/oem/ibm/libpldmresponder/file_io_type_progress_src.cpp
new file mode 100644
index 0000000..3d51039
--- /dev/null
+++ b/oem/ibm/libpldmresponder/file_io_type_progress_src.cpp
@@ -0,0 +1,79 @@
+#include "file_io_type_progress_src.hpp"
+
+#include "common/utils.hpp"
+
+#include <iostream>
+
+namespace pldm
+{
+
+namespace responder
+{
+
+int ProgressCodeHandler::setRawBootProperty(
+    const std::tuple<uint64_t, std::vector<uint8_t>>& progressCodeBuffer)
+{
+    static constexpr auto RawObjectPath =
+        "/xyz/openbmc_project/state/boot/raw0";
+    static constexpr auto RawInterface = "xyz.openbmc_project.State.Boot.Raw";
+    static constexpr auto FreedesktopInterface =
+        "org.freedesktop.DBus.Properties";
+    static constexpr auto RawProperty = "Value";
+    static constexpr auto SetMethod = "Set";
+
+    auto& bus = pldm::utils::DBusHandler::getBus();
+
+    try
+    {
+        auto service =
+            pldm::utils::DBusHandler().getService(RawObjectPath, RawInterface);
+        auto method = bus.new_method_call(service.c_str(), RawObjectPath,
+                                          FreedesktopInterface, SetMethod);
+        method.append(RawInterface, RawProperty,
+                      std::variant<std::tuple<uint64_t, std::vector<uint8_t>>>(
+                          progressCodeBuffer));
+
+        bus.call_noreply(method);
+    }
+    catch (const std::exception& e)
+    {
+        std::cerr << "failed to make a d-bus call to host-postd daemon, ERROR="
+                  << e.what() << "\n";
+        return PLDM_ERROR;
+    }
+
+    return PLDM_SUCCESS;
+}
+
+int ProgressCodeHandler::write(const char* buffer, uint32_t /*offset*/,
+                               uint32_t& length,
+                               oem_platform::Handler* /*oemPlatformHandler*/)
+{
+    static constexpr auto StartOffset = 40;
+    static constexpr auto EndOffset = 48;
+    if (buffer != nullptr)
+    {
+        // read the data from the pointed location
+        std::vector<uint8_t> secondaryCode(buffer, buffer + length);
+
+        // Get the primary code from the offset 40 bytes in the received buffer
+
+        std::vector<uint8_t> primaryCodeArray(
+            secondaryCode.begin() + StartOffset,
+            secondaryCode.begin() + EndOffset);
+        uint64_t primaryCode = 0;
+
+        // form a uint64_t using uint8_t[8]
+        for (int i = 0; i < 8; i++)
+            primaryCode |= (uint64_t)primaryCodeArray[i] << 8 * i;
+
+        std::cout << "Primary Progress Code in Hex : " << std::hex
+                  << primaryCode << std::endl;
+
+        return setRawBootProperty(std::make_tuple(primaryCode, secondaryCode));
+    }
+    return PLDM_ERROR;
+}
+
+} // namespace responder
+} // namespace pldm
diff --git a/oem/ibm/libpldmresponder/file_io_type_progress_src.hpp b/oem/ibm/libpldmresponder/file_io_type_progress_src.hpp
new file mode 100644
index 0000000..a223f1a
--- /dev/null
+++ b/oem/ibm/libpldmresponder/file_io_type_progress_src.hpp
@@ -0,0 +1,73 @@
+#pragma once
+
+#include "file_io_by_type.hpp"
+
+namespace pldm
+{
+
+namespace responder
+{
+
+/** @class ProgressCodeHandler
+ *
+ * @brief Inherits and implemented FileHandler. This class is used
+ * to read the Progress SRC's from the Host.
+ */
+class ProgressCodeHandler : public FileHandler
+{
+  public:
+    /** @brief ProgressCodeHandler constructor
+     */
+    ProgressCodeHandler(uint32_t fileHandle) : FileHandler(fileHandle)
+    {}
+
+    int writeFromMemory(uint32_t /*offset*/, uint32_t /*length*/,
+                        uint64_t /*address*/,
+                        oem_platform::Handler* /*oemPlatformHandler*/) override
+    {
+        return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
+    }
+
+    int write(const char* buffer, uint32_t offset, uint32_t& length,
+              oem_platform::Handler* oemPlatformHandler) override;
+
+    int readIntoMemory(uint32_t /*offset*/, uint32_t& /*length*/,
+                       uint64_t /*address*/,
+                       oem_platform::Handler* /*oemPlatformHandler*/) override
+    {
+        return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
+    }
+
+    int read(uint32_t /*offset*/, uint32_t& /*length*/, Response& /*response*/,
+             oem_platform::Handler* /*oemPlatformHandler*/) override
+    {
+        return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
+    }
+
+    int fileAck(uint8_t /*fileStatus*/) override
+    {
+        return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
+    }
+
+    int newFileAvailable(uint64_t /*length*/) override
+    {
+        return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
+    }
+
+    /** @brief method to set the dbus Raw value Property with
+     * the obtained progress code from the host.
+     *
+     *  @param[in] progressCodeBuffer - the progress Code SRC Buffer
+     */
+    virtual int setRawBootProperty(
+        const std::tuple<uint64_t, std::vector<uint8_t>>& progressCodeBuffer);
+
+    /** @brief ProgressCodeHandler destructor
+     */
+
+    ~ProgressCodeHandler()
+    {}
+};
+
+} // namespace responder
+} // namespace pldm