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/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