ibm-oem: add FileAck handler for PELs

Extend the FileAck* commands to let the host firmware to ack PELs it has
received from the BMC.

Signed-off-by: vkaverap <vkaverap@in.ibm.com>
Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
Change-Id: Iafc1c92c64c8ea7a51367c2c36842613af1f46b5
diff --git a/oem/ibm/libpldmresponder/file_io.cpp b/oem/ibm/libpldmresponder/file_io.cpp
index d191d3d..177fe3f 100644
--- a/oem/ibm/libpldmresponder/file_io.cpp
+++ b/oem/ibm/libpldmresponder/file_io.cpp
@@ -659,6 +659,46 @@
     return response;
 }
 
+Response Handler::fileAck(const pldm_msg* request, size_t payloadLength)
+{
+    Response response(sizeof(pldm_msg_hdr) + PLDM_FILE_ACK_RESP_BYTES);
+    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+
+    if (payloadLength != PLDM_FILE_ACK_REQ_BYTES)
+    {
+        encode_file_ack_resp(request->hdr.instance_id,
+                             PLDM_ERROR_INVALID_LENGTH, responsePtr);
+        return response;
+    }
+    uint16_t fileType{};
+    uint32_t fileHandle{};
+    uint8_t fileStatus{};
+
+    auto rc = decode_file_ack_req(request, payloadLength, &fileType,
+                                  &fileHandle, &fileStatus);
+    if (rc != PLDM_SUCCESS)
+    {
+        encode_file_ack_resp(request->hdr.instance_id, rc, responsePtr);
+        return response;
+    }
+
+    std::unique_ptr<FileHandler> handler{};
+    try
+    {
+        handler = getHandlerByType(fileType, fileHandle);
+    }
+    catch (const InternalFailure& e)
+    {
+        encode_file_ack_resp(request->hdr.instance_id, PLDM_INVALID_FILE_TYPE,
+                             responsePtr);
+        return response;
+    }
+
+    rc = handler->fileAck(fileStatus);
+    encode_file_ack_resp(request->hdr.instance_id, rc, responsePtr);
+    return response;
+}
+
 } // namespace oem_ibm
 } // namespace responder
 } // namespace pldm
diff --git a/oem/ibm/libpldmresponder/file_io.hpp b/oem/ibm/libpldmresponder/file_io.hpp
index 5c357d5..a22a8c8 100644
--- a/oem/ibm/libpldmresponder/file_io.hpp
+++ b/oem/ibm/libpldmresponder/file_io.hpp
@@ -184,6 +184,10 @@
                          [this](const pldm_msg* request, size_t payloadLength) {
                              return this->writeFile(request, payloadLength);
                          });
+        handlers.emplace(PLDM_FILE_ACK,
+                         [this](const pldm_msg* request, size_t payloadLength) {
+                             return this->fileAck(request, payloadLength);
+                         });
     }
 
     /** @brief Handler for readFileIntoMemory command
@@ -260,6 +264,8 @@
      *  @return PLDM response message
      */
     Response writeFile(const pldm_msg* request, size_t payloadLength);
+
+    Response fileAck(const pldm_msg* request, size_t payloadLength);
 };
 
 } // namespace oem_ibm
diff --git a/oem/ibm/libpldmresponder/file_io_by_type.hpp b/oem/ibm/libpldmresponder/file_io_by_type.hpp
index b8621f5..b970886 100644
--- a/oem/ibm/libpldmresponder/file_io_by_type.hpp
+++ b/oem/ibm/libpldmresponder/file_io_by_type.hpp
@@ -48,6 +48,8 @@
      */
     virtual int read(uint32_t offset, uint32_t& length, Response& response) = 0;
 
+    virtual int fileAck(uint8_t fileStatus) = 0;
+
     /** @brief Method to read an oem file type's content into the PLDM response.
      *  @param[in] filePath - file to read from
      *  @param[in] offset - offset to read
diff --git a/oem/ibm/libpldmresponder/file_io_type_lid.hpp b/oem/ibm/libpldmresponder/file_io_type_lid.hpp
index d3a48a5..3a3332a 100644
--- a/oem/ibm/libpldmresponder/file_io_type_lid.hpp
+++ b/oem/ibm/libpldmresponder/file_io_type_lid.hpp
@@ -49,6 +49,11 @@
         return readFile(lidPath, offset, length, response);
     }
 
+    virtual int fileAck(uint8_t /*fileStatus*/)
+    {
+        return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
+    }
+
     /** @brief LidHandler destructor
      */
     ~LidHandler()
diff --git a/oem/ibm/libpldmresponder/file_io_type_pel.cpp b/oem/ibm/libpldmresponder/file_io_type_pel.cpp
index 06ced26..8029b47 100644
--- a/oem/ibm/libpldmresponder/file_io_type_pel.cpp
+++ b/oem/ibm/libpldmresponder/file_io_type_pel.cpp
@@ -141,6 +141,29 @@
     return rc;
 }
 
+int PelHandler::fileAck(uint8_t /*fileStatus*/)
+{
+    static constexpr auto logObjPath = "/xyz/openbmc_project/logging";
+    static constexpr auto logInterface = "org.open_power.Logging.PEL";
+    static sdbusplus::bus::bus bus = sdbusplus::bus::new_default();
+
+    try
+    {
+        auto service = getService(bus, logObjPath, logInterface);
+        auto method = bus.new_method_call(service.c_str(), logObjPath,
+                                          logInterface, "HostAck");
+        method.append(fileHandle);
+        bus.call_noreply(method);
+    }
+    catch (const std::exception& e)
+    {
+        std::cerr << "HostAck D-Bus call failed";
+        return PLDM_ERROR;
+    }
+
+    return PLDM_SUCCESS;
+}
+
 int PelHandler::storePel(std::string&& pelFileName)
 {
     static constexpr auto logObjPath = "/xyz/openbmc_project/logging";
diff --git a/oem/ibm/libpldmresponder/file_io_type_pel.hpp b/oem/ibm/libpldmresponder/file_io_type_pel.hpp
index d2fb5cc..34f4907 100644
--- a/oem/ibm/libpldmresponder/file_io_type_pel.hpp
+++ b/oem/ibm/libpldmresponder/file_io_type_pel.hpp
@@ -29,6 +29,8 @@
                                uint64_t address);
     virtual int read(uint32_t offset, uint32_t& length, Response& response);
 
+    virtual int fileAck(uint8_t fileStatus);
+
     /** @brief method to store a pel file in tempfs and send
      *  d-bus notification to pel daemon that it is ready for consumption
      *