oem-ibm: Add support for fileAckWithMetaData command

The commit adds handler support for the oem-ibm File I/O
fileAckWithMetaData command.

Tested: A fileAckWithMetaData command was honored.

Change-Id: Ief2cf7185ad47837a408124586e15895ef60e95b
Signed-off-by: Pavithra Barithaya <pavithrabarithaya07@gmail.com>
diff --git a/oem/ibm/libpldmresponder/file_io.cpp b/oem/ibm/libpldmresponder/file_io.cpp
index f223819..0ce4b1c 100644
--- a/oem/ibm/libpldmresponder/file_io.cpp
+++ b/oem/ibm/libpldmresponder/file_io.cpp
@@ -1145,6 +1145,54 @@
     return response;
 }
 
+Response Handler::fileAckWithMetaData(const pldm_msg* request,
+                                      size_t payloadLength)
+{
+    Response response(
+        sizeof(pldm_msg_hdr) + PLDM_FILE_ACK_WITH_META_DATA_RESP_BYTES);
+
+    if (payloadLength != PLDM_FILE_ACK_WITH_META_DATA_REQ_BYTES)
+    {
+        return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
+    }
+    uint16_t fileType{};
+    uint32_t fileHandle{};
+    uint8_t fileStatus{};
+    uint32_t fileMetaData1{};
+    uint32_t fileMetaData2{};
+    uint32_t fileMetaData3{};
+    uint32_t fileMetaData4{};
+
+    auto rc = decode_file_ack_with_meta_data_req(
+        request, payloadLength, &fileType, &fileHandle, &fileStatus,
+        &fileMetaData1, &fileMetaData2, &fileMetaData3, &fileMetaData4);
+
+    if (rc != PLDM_SUCCESS)
+    {
+        return CmdHandler::ccOnlyResponse(request, rc);
+    }
+
+    std::unique_ptr<FileHandler> handler{};
+    try
+    {
+        handler = getHandlerByType(fileType, fileHandle);
+    }
+    catch (const InternalFailure& e)
+    {
+        error(
+            "Unknown file type, '{TYPE}' in fileAckWithMetaData and error - {ERROR}",
+            "TYPE", fileType, "ERROR", e);
+        return CmdHandler::ccOnlyResponse(request, PLDM_INVALID_FILE_TYPE);
+    }
+
+    rc = handler->fileAckWithMetaData(fileStatus, fileMetaData1, fileMetaData2,
+                                      fileMetaData3, fileMetaData4);
+    auto responsePtr = new (response.data()) pldm_msg;
+    encode_file_ack_with_meta_data_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 cccd919..5d70f53 100644
--- a/oem/ibm/libpldmresponder/file_io.hpp
+++ b/oem/ibm/libpldmresponder/file_io.hpp
@@ -231,7 +231,11 @@
             [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
                 return this->newFileAvailable(request, payloadLength);
             });
-
+        handlers.emplace(
+            PLDM_FILE_ACK_WITH_META_DATA,
+            [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
+                return this->fileAckWithMetaData(request, payloadLength);
+            });
         resDumpMatcher = std::make_unique<sdbusplus::bus::match_t>(
             pldm::utils::DBusHandler::getBus(),
             sdbusplus::bus::match::rules::interfacesAdded() +
@@ -415,6 +419,15 @@
      */
     Response newFileAvailable(const pldm_msg* request, size_t payloadLength);
 
+    /** @brief Handler for fileAckWithMetaData command
+     *
+     *  @param[in] request - PLDM request msg
+     *  @param[in] payloadLength - length of the message payload
+     *
+     *  @return PLDM response message
+     */
+    Response fileAckWithMetaData(const pldm_msg* request, size_t payloadLength);
+
   private:
     oem_platform::Handler* oemPlatformHandler;
     using DBusInterfaceAdded = std::vector<std::pair<
diff --git a/oem/ibm/libpldmresponder/file_io_by_type.hpp b/oem/ibm/libpldmresponder/file_io_by_type.hpp
index c9056e9..30af4d1 100644
--- a/oem/ibm/libpldmresponder/file_io_by_type.hpp
+++ b/oem/ibm/libpldmresponder/file_io_by_type.hpp
@@ -89,6 +89,21 @@
     virtual int readFile(const std::string& filePath, uint32_t offset,
                          uint32_t& length, Response& response);
 
+    /** @brief Method to process a file ack with meta data notification from the
+     *  host. The bmc can chose to do different actions based on the file type.
+     *
+     *  @param[in] fileStatus - Status of the file transfer
+     *  @param[in] metaDataValue1 - value of meta data sent by host
+     *  @param[in] metaDataValue2 - value of meta data sent by host
+     *  @param[in] metaDataValue3 - value of meta data sent by host
+     *  @param[in] metaDataValue4 - value of meta data sent by host
+     *
+     *  @return PLDM status code
+     */
+    virtual int fileAckWithMetaData(
+        uint8_t fileStatus, uint32_t metaDataValue1, uint32_t metaDataValue2,
+        uint32_t metaDataValue3, uint32_t metaDataValue4) = 0;
+
     /** @brief Method to do the file content transfer ove DMA between host and
      *  bmc. This method is made virtual to be overridden in test case. And need
      *  not be defined in other child classes
diff --git a/oem/ibm/libpldmresponder/file_io_type_dump.hpp b/oem/ibm/libpldmresponder/file_io_type_dump.hpp
index c11bcae..a474f71 100644
--- a/oem/ibm/libpldmresponder/file_io_type_dump.hpp
+++ b/oem/ibm/libpldmresponder/file_io_type_dump.hpp
@@ -40,6 +40,14 @@
 
     virtual int fileAck(uint8_t fileStatus);
 
+    virtual int fileAckWithMetaData(
+        uint8_t /*fileStatus*/, uint32_t /*metaDataValue1*/,
+        uint32_t /*metaDataValue2*/, uint32_t /*metaDataValue3*/,
+        uint32_t /*metaDataValue4*/)
+    {
+        return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
+    }
+
     std::string findDumpObjPath(uint32_t fileHandle);
     std::string getOffloadUri(uint32_t fileHandle);
 
diff --git a/oem/ibm/libpldmresponder/file_io_type_lid.hpp b/oem/ibm/libpldmresponder/file_io_type_lid.hpp
index cb0e697..dd2ca3d 100644
--- a/oem/ibm/libpldmresponder/file_io_type_lid.hpp
+++ b/oem/ibm/libpldmresponder/file_io_type_lid.hpp
@@ -308,6 +308,14 @@
         return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
     }
 
+    virtual int fileAckWithMetaData(
+        uint8_t /*fileStatus*/, uint32_t /*metaDataValue1*/,
+        uint32_t /*metaDataValue2*/, uint32_t /*metaDataValue3*/,
+        uint32_t /*metaDataValue4*/)
+    {
+        return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
+    }
+
     /** @brief LidHandler destructor
      */
     ~LidHandler() {}
diff --git a/oem/ibm/libpldmresponder/file_io_type_pel.hpp b/oem/ibm/libpldmresponder/file_io_type_pel.hpp
index 02cca16..bd88409 100644
--- a/oem/ibm/libpldmresponder/file_io_type_pel.hpp
+++ b/oem/ibm/libpldmresponder/file_io_type_pel.hpp
@@ -36,6 +36,14 @@
 
     virtual int fileAck(uint8_t fileStatus);
 
+    virtual int fileAckWithMetaData(
+        uint8_t /*fileStatus*/, uint32_t /*metaDataValue1*/,
+        uint32_t /*metaDataValue2*/, uint32_t /*metaDataValue3*/,
+        uint32_t /*metaDataValue4*/)
+    {
+        return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
+    }
+
     /** @brief method to store a pel file in tempfs and send
      *  d-bus notification to pel daemon that it is ready for consumption
      *
diff --git a/oem/ibm/libpldmresponder/file_io_type_progress_src.hpp b/oem/ibm/libpldmresponder/file_io_type_progress_src.hpp
index 4beb433..deecf93 100644
--- a/oem/ibm/libpldmresponder/file_io_type_progress_src.hpp
+++ b/oem/ibm/libpldmresponder/file_io_type_progress_src.hpp
@@ -62,6 +62,14 @@
         const std::tuple<std::vector<uint8_t>, std::vector<uint8_t>>&
             progressCodeBuffer);
 
+    virtual int fileAckWithMetaData(
+        uint8_t /*fileStatus*/, uint32_t /*metaDataValue1*/,
+        uint32_t /*metaDataValue2*/, uint32_t /*metaDataValue3*/,
+        uint32_t /*metaDataValue4*/) override
+    {
+        return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
+    }
+
     /** @brief ProgressCodeHandler destructor
      */