OEM-IBM: Add APIs for fileAckWithMetaData and
newFileAvailableWithMetaData for VMI.

Tested with latest SDK environment.

Change-Id: Ib796fb5c35438b340c28e2db7c118cdc76a13619
Signed-off-by: Sridevi Ramesh <sridevra@in.ibm.com>
diff --git a/oem/ibm/libpldmresponder/file_io_type_cert.cpp b/oem/ibm/libpldmresponder/file_io_type_cert.cpp
index 03f577a..83d082e 100644
--- a/oem/ibm/libpldmresponder/file_io_type_cert.cpp
+++ b/oem/ibm/libpldmresponder/file_io_type_cert.cpp
@@ -15,7 +15,8 @@
 
 namespace responder
 {
-
+constexpr auto certObjPath = "/xyz/openbmc_project/certs/ca/entry/";
+constexpr auto certEntryIntf = "xyz.openbmc_project.Certs.Entry";
 static constexpr auto certFilePath = "/var/lib/ibm/bmcweb/";
 
 CertMap CertHandler::certMap;
@@ -27,7 +28,8 @@
     auto it = certMap.find(certType);
     if (it == certMap.end())
     {
-        std::cerr << "file for type " << certType << " doesn't exist\n";
+        std::cerr << "CertHandler::writeFromMemory:file for type " << certType
+                  << " doesn't exist\n";
         return PLDM_ERROR;
     }
 
@@ -68,6 +70,9 @@
 int CertHandler::read(uint32_t offset, uint32_t& length, Response& response,
                       oem_platform::Handler* /*oemPlatformHandler*/)
 {
+    std::cout
+        << "CertHandler::read:Read file response for Sign CSR, file handle: "
+        << fileHandle << std::endl;
     std::string filePath = certFilePath;
     filePath += "CSR_" + std::to_string(fileHandle);
     if (certType != PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
@@ -89,7 +94,8 @@
     auto it = certMap.find(certType);
     if (it == certMap.end())
     {
-        std::cerr << "file for type " << certType << " doesn't exist\n";
+        std::cerr << "CertHandler::write:file for type " << certType
+                  << " doesn't exist\n";
         return PLDM_ERROR;
     }
 
@@ -97,14 +103,14 @@
     int rc = lseek(fd, offset, SEEK_SET);
     if (rc == -1)
     {
-        std::cerr << "lseek failed, ERROR=" << errno << ", OFFSET=" << offset
-                  << "\n";
+        std::cerr << "CertHandler::write:lseek failed, ERROR=" << errno
+                  << ", OFFSET=" << offset << "\n";
         return PLDM_ERROR;
     }
     rc = ::write(fd, buffer, length);
     if (rc == -1)
     {
-        std::cerr << "file write failed, ERROR=" << errno
+        std::cerr << "CertHandler::write:file write failed, ERROR=" << errno
                   << ", LENGTH=" << length << ", OFFSET=" << offset << "\n";
         return PLDM_ERROR;
     }
@@ -145,9 +151,10 @@
             }
             catch (const std::exception& e)
             {
-                std::cerr << "failed to set Client certificate, "
-                             "ERROR="
-                          << e.what() << "\n";
+                std::cerr
+                    << "CertHandler::write:failed to set Client certificate, "
+                       "ERROR="
+                    << e.what() << "\n";
                 return PLDM_ERROR;
             }
             PropertyValue valueStatus{
@@ -157,13 +164,16 @@
                                           certEntryIntf, "Status", "string"};
             try
             {
+                std::cout
+                    << "CertHandler::write:Client cert write, status: complete. File handle: "
+                    << fileHandle << std::endl;
                 pldm::utils::DBusHandler().setDbusProperty(dbusMappingStatus,
                                                            valueStatus);
             }
             catch (const std::exception& e)
             {
                 std::cerr
-                    << "failed to set status property of certicate entry, "
+                    << "CertHandler::write:failed to set status property of certicate entry, "
                        "ERROR="
                     << e.what() << "\n";
                 return PLDM_ERROR;
@@ -177,12 +187,15 @@
                                     certEntryIntf, "Status", "string"};
             try
             {
+                std::cout
+                    << "CertHandler::write:Client cert write, status: Bad CSR. File handle: "
+                    << fileHandle << std::endl;
                 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
             }
             catch (const std::exception& e)
             {
                 std::cerr
-                    << "failed to set status property of certicate entry, "
+                    << "CertHandler::write:failed to set status property of certicate entry, "
                        "ERROR="
                     << e.what() << "\n";
                 return PLDM_ERROR;
@@ -207,6 +220,9 @@
     }
     if (certType == PLDM_FILE_TYPE_SIGNED_CERT)
     {
+        std::cout
+            << "CertHandler::newFileAvailable:new file available client cert file, file handle: "
+            << fileHandle << std::endl;
         fileFd = open(
             (filePath + "ClientCert_" + std::to_string(fileHandle)).c_str(),
             flags, S_IRUSR | S_IWUSR);
@@ -218,13 +234,116 @@
     }
     if (fileFd == -1)
     {
-        std::cerr << "failed to open file for type " << certType
-                  << " ERROR=" << errno << "\n";
+        std::cerr
+            << "CertHandler::newFileAvailable:failed to open file for type "
+            << certType << " ERROR=" << errno << "\n";
         return PLDM_ERROR;
     }
     certMap.emplace(certType, std::tuple(fileFd, length));
     return PLDM_SUCCESS;
 }
 
+int CertHandler::newFileAvailableWithMetaData(uint64_t length,
+                                              uint32_t metaDataValue1,
+                                              uint32_t /*metaDataValue2*/,
+                                              uint32_t /*metaDataValue3*/,
+                                              uint32_t /*metaDataValue4*/)
+{
+    fs::create_directories(certFilePath);
+    fs::permissions(certFilePath,
+                    fs::perms::others_read | fs::perms::owner_write);
+    int fileFd = -1;
+    int flags = O_WRONLY | O_CREAT | O_TRUNC;
+    std::string filePath = certFilePath;
+
+    if (certType == PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    if (certType == PLDM_FILE_TYPE_SIGNED_CERT)
+    {
+        if (metaDataValue1 == PLDM_SUCCESS)
+        {
+            std::cerr
+                << "CertHandler::newFileAvailableWithMetaData:new file available client cert file, file handle: "
+                << fileHandle << std::endl;
+            fileFd = open(
+                (filePath + "ClientCert_" + std::to_string(fileHandle)).c_str(),
+                flags, S_IRUSR | S_IWUSR);
+        }
+        else if (metaDataValue1 == PLDM_INVALID_CERT_DATA)
+        {
+            std::cerr
+                << "newFileAvailableWithMetaData:client cert file Invalid data, file handle: "
+                << fileHandle << std::endl;
+            DBusMapping dbusMapping{certObjPath + std::to_string(fileHandle),
+                                    certEntryIntf, "Status", "string"};
+            std::string status = "xyz.openbmc_project.Certs.Entry.State.BadCSR";
+            PropertyValue value{status};
+            try
+            {
+                pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
+            }
+            catch (const std::exception& e)
+            {
+                std::cerr
+                    << "newFileAvailableWithMetaData:Failed to set status property of certicate entry, "
+                       "ERROR="
+                    << e.what() << "\n";
+                return PLDM_ERROR;
+            }
+        }
+    }
+    else if (certType == PLDM_FILE_TYPE_ROOT_CERT)
+    {
+        fileFd =
+            open((filePath + "RootCert").c_str(), flags, S_IRUSR | S_IWUSR);
+    }
+    if (fileFd == -1)
+    {
+        std::cerr
+            << "newFileAvailableWithMetaData:failed to open file for type "
+            << certType << " ERROR=" << errno << "\n";
+        return PLDM_ERROR;
+    }
+    certMap.emplace(certType, std::tuple(fileFd, length));
+    return PLDM_SUCCESS;
+}
+
+int CertHandler::fileAckWithMetaData(uint8_t fileStatus,
+                                     uint32_t /*metaDataValue1*/,
+                                     uint32_t /*metaDataValue2*/,
+                                     uint32_t /*metaDataValue3*/,
+                                     uint32_t /*metaDataValue4*/)
+{
+    if (certType == PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
+    {
+        DBusMapping dbusMapping{certObjPath + std::to_string(fileHandle),
+                                certEntryIntf, "Status", "string"};
+        PropertyValue value = "xyz.openbmc_project.Certs.Entry.State.Pending";
+        if (fileStatus == PLDM_ERROR_INVALID_DATA)
+        {
+            value = "xyz.openbmc_project.Certs.Entry.State.BadCSR";
+        }
+        else if (fileStatus == PLDM_ERROR_NOT_READY)
+        {
+            value = "xyz.openbmc_project.Certs.Entry.State.Pending";
+        }
+        try
+        {
+            pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
+        }
+        catch (const std::exception& e)
+        {
+            std::cerr
+                << "CertHandler::fileAckWithMetaData:Failed to set status property of certicate entry, "
+                   "ERROR="
+                << e.what() << "\n";
+            return PLDM_ERROR;
+        }
+    }
+    return PLDM_SUCCESS;
+}
+
 } // namespace responder
 } // namespace pldm
diff --git a/oem/ibm/libpldmresponder/file_io_type_cert.hpp b/oem/ibm/libpldmresponder/file_io_type_cert.hpp
index ee34575..4e4ad6b 100644
--- a/oem/ibm/libpldmresponder/file_io_type_cert.hpp
+++ b/oem/ibm/libpldmresponder/file_io_type_cert.hpp
@@ -8,7 +8,6 @@
 {
 namespace responder
 {
-
 using Fd = int;
 using RemainingSize = uint64_t;
 using CertDetails = std::tuple<Fd, RemainingSize>;
@@ -48,6 +47,18 @@
 
     virtual int newFileAvailable(uint64_t length);
 
+    virtual int fileAckWithMetaData(uint8_t /*fileStatus*/,
+                                    uint32_t /*metaDataValue1*/,
+                                    uint32_t /*metaDataValue2*/,
+                                    uint32_t /*metaDataValue3*/,
+                                    uint32_t /*metaDataValue4*/);
+
+    virtual int newFileAvailableWithMetaData(uint64_t length,
+                                             uint32_t metaDataValue1,
+                                             uint32_t /*metaDataValue2*/,
+                                             uint32_t /*metaDataValue3*/,
+                                             uint32_t /*metaDataValue4*/);
+
     /** @brief CertHandler destructor
      */
     ~CertHandler()
@@ -57,6 +68,10 @@
     uint16_t certType;      //!< type of the certificate
     static CertMap certMap; //!< holds the fd and remaining read/write size for
                             //!< each certificate
+    enum SignedCertStatus
+    {
+        PLDM_INVALID_CERT_DATA = 0X03
+    };
 };
 } // namespace responder
 } // namespace pldm