From b9106871dcc7cfe174c61ca8a6b2e3013d1720c6 Mon Sep 17 00:00:00 2001
From: roly <Rolyli.Li@luxshare-ict.com>
Date: Thu, 14 Nov 2024 19:18:00 +0800
Subject: [PATCH] Add ReleaseDate for Software interface

---
 image_manager.cpp |  5 ++++-
 item_updater.cpp  | 25 ++++++++++++++++++++-----
 meson.build       |  1 +
 version.cpp       | 24 ++++++++++++++++++++++++
 version.hpp       | 18 +++++++++++++++++-
 5 files changed, 66 insertions(+), 7 deletions(-)

diff --git a/image_manager.cpp b/image_manager.cpp
index baa0571..75cd541 100644
--- a/image_manager.cpp
+++ b/image_manager.cpp
@@ -191,6 +191,9 @@ int Manager::processImage(const std::string& tarFilePath)
     std::string extendedVersion = Version::getValue(manifestPath.string(),
                                                     "ExtendedVersion");
 
+    // Get ReleaseDate
+    std::string releaseDate = Version::getBMCReleaseDate(OS_RELEASE_FILE);
+
     // Get CompatibleNames
     std::vector<std::string> compatibleNames =
         Version::getRepeatedValues(manifestPath.string(), "CompatibleName");
@@ -219,7 +222,7 @@ int Manager::processImage(const std::string& tarFilePath)
 
         // Create Version object
         auto versionPtr = std::make_unique<Version>(
-            bus, objPath, version, purpose, extendedVersion,
+            bus, objPath, version, purpose, extendedVersion, releaseDate,
             imageDirPath.string(), compatibleNames,
             std::bind(&Manager::erase, this, std::placeholders::_1), id);
         versionPtr->deleteObject =
diff --git a/item_updater.cpp b/item_updater.cpp
index d8348e3..36bf5b3 100644
--- a/item_updater.cpp
+++ b/item_updater.cpp
@@ -48,6 +48,7 @@ void ItemUpdater::createActivation(sdbusplus::message_t& msg)
     sdbusplus::message::object_path objPath;
     auto purpose = VersionPurpose::Unknown;
     std::string extendedVersion;
+    std::string releaseDate;
     std::string version;
     std::map<std::string,
              std::map<std::string,
@@ -109,6 +110,16 @@ void ItemUpdater::createActivation(sdbusplus::message_t& msg)
                 }
             }
         }
+        else if (intf.first == RELEASE_DATE_IFACE)
+        {
+            for (const auto& property : intf.second)
+            {
+                if (property.first == "ReleaseDate")
+                {
+                    releaseDate = std::get<std::string>(property.second);
+                }
+            }
+        }
         else if (intf.first == COMPATIBLE_IFACE)
         {
             for (const auto& property : intf.second)
@@ -159,7 +170,7 @@ void ItemUpdater::createActivation(sdbusplus::message_t& msg)
         }
 
         auto versionPtr = std::make_unique<VersionClass>(
-            bus, path, version, purpose, extendedVersion, filePath,
+            bus, path, version, purpose, extendedVersion, releaseDate, filePath,
             compatibleNames,
             std::bind(&ItemUpdater::erase, this, std::placeholders::_1),
             versionId);
@@ -278,6 +289,10 @@ void ItemUpdater::processBMCImage()
             // Read os-release from /etc/ to get the BMC extended version
             std::string extendedVersion =
                 VersionClass::getBMCExtendedVersion(osRelease);
+            
+            // Read os-release from /etc/ to get the BMC release date
+            std::string releaseDate =
+                VersionClass::getBMCReleaseDate(osRelease);
 
             auto path = fs::path(SOFTWARE_OBJPATH) / id;
 
@@ -307,7 +322,7 @@ void ItemUpdater::processBMCImage()
 
             // Create Version instance for this version.
             auto versionPtr = std::make_unique<VersionClass>(
-                bus, path, version, purpose, extendedVersion, flashId,
+                bus, path, version, purpose, extendedVersion, releaseDate, flashId,
                 std::vector<std::string>(),
                 std::bind(&ItemUpdater::erase, this, std::placeholders::_1),
                 id);
@@ -876,7 +891,7 @@ void ItemUpdater::createBIOSObject()
         // Do nothing;
     };
     biosVersion = std::make_unique<VersionClass>(
-        bus, path, version, VersionPurpose::Host, "", "",
+        bus, path, version, VersionPurpose::Host, "", "", "",
         std::vector<std::string>(),
         std::bind(dummyErase, std::placeholders::_1), "");
     biosVersion->deleteObject =
@@ -910,7 +925,7 @@ void ItemUpdater::createCPLDObject()
         // Do nothing;
     };
     cpldVersion = std::make_unique<VersionClass>(
-        bus, path, version, VersionPurpose::CPLD, "", "",
+        bus, path, version, VersionPurpose::CPLD, "", "", "",
         std::vector<std::string>(),
         std::bind(dummyErase, std::placeholders::_1), "");
     cpldVersion->deleteObject =
@@ -944,7 +959,7 @@ void ItemUpdater::createFBCPLDObject()
         // Do nothing;
     };
     FBcpldVersion = std::make_unique<VersionClass>(
-        bus, path, version, VersionPurpose::FBCPLD, "", "",
+        bus, path, version, VersionPurpose::FBCPLD, "", "", "",
         std::vector<std::string>(),
         std::bind(dummyErase, std::placeholders::_1), "");
     cpldVersion->deleteObject =
diff --git a/meson.build b/meson.build
index 009dcef..68f1f91 100644
--- a/meson.build
+++ b/meson.build
@@ -40,6 +40,7 @@ conf.set_quoted('SYSTEMD_INTERFACE', 'org.freedesktop.systemd1.Manager')
 conf.set_quoted('VERSION_BUSNAME', 'xyz.openbmc_project.Software.Version')
 conf.set_quoted('VERSION_IFACE', 'xyz.openbmc_project.Software.Version')
 conf.set_quoted('EXTENDED_VERSION_IFACE', 'xyz.openbmc_project.Software.ExtendedVersion')
+conf.set_quoted('RELEASE_DATE_IFACE', 'xyz.openbmc_project.Software.ReleaseDate')
 conf.set_quoted('COMPATIBLE_IFACE', 'xyz.openbmc_project.Inventory.Decorator.Compatible')
 
 # Names of the forward and reverse associations
diff --git a/version.cpp b/version.cpp
index b8b1247..f40c03e 100644
--- a/version.cpp
+++ b/version.cpp
@@ -178,6 +178,30 @@ std::string Version::getBMCExtendedVersion(const std::string& releaseFilePath)
     return extendedVersion;
 }
 
+std::string Version::getBMCReleaseDate(const std::string& releaseFilePath)
+{
+    std::string releaseDateKey = "BUILD_DATE=";
+    std::string releaseDateValue{};
+    std::string releaseDate{};
+    std::ifstream efile(releaseFilePath);
+    std::string line;
+
+    while (getline(efile, line))
+    {
+        if (line.substr(0, releaseDateKey.size())
+                .find(releaseDateKey) != std::string::npos)
+        {
+            releaseDateValue = line.substr(releaseDateKey.size());
+            std::size_t pos = releaseDateValue.find_first_of('"') + 1;
+            releaseDate = releaseDateValue.substr(
+                pos, releaseDateValue.find_last_of('"') - pos);
+            break;
+        }
+    }
+
+    return releaseDate;
+}
+
 std::string Version::getBMCVersion(const std::string& releaseFilePath)
 {
     std::string versionKey = "VERSION_ID=";
diff --git a/version.hpp b/version.hpp
index 5c74f99..d54b41d 100644
--- a/version.hpp
+++ b/version.hpp
@@ -5,6 +5,7 @@
 #include "xyz/openbmc_project/Object/Delete/server.hpp"
 #include "xyz/openbmc_project/Software/ExtendedVersion/server.hpp"
 #include "xyz/openbmc_project/Software/Version/server.hpp"
+#include "xyz/openbmc_project/Software/ReleaseDate/server.hpp"
 
 #include <sdbusplus/bus.hpp>
 
@@ -23,6 +24,7 @@ typedef std::function<void(std::string)> eraseFunc;
 
 using VersionInherit = sdbusplus::server::object_t<
     sdbusplus::xyz::openbmc_project::Software::server::ExtendedVersion,
+    sdbusplus::xyz::openbmc_project::Software::server::ReleaseDate,
     sdbusplus::xyz::openbmc_project::Software::server::Version,
     sdbusplus::xyz::openbmc_project::Common::server::FilePath,
     sdbusplus::xyz::openbmc_project::Inventory::Decorator::server::Compatible>;
@@ -76,13 +78,15 @@ class Version : public VersionInherit
      * @param[in] versionString   - The version string
      * @param[in] versionPurpose  - The version purpose
      * @param[in] extVersion      - The extended version
+     * @param[in] relDate     - The firmware release date
      * @param[in] filePath        - The image filesystem path
      * @param[in] compatibleNames - The device compatibility names
      * @param[in] callback        - The eraseFunc callback
      */
     Version(sdbusplus::bus_t& bus, const std::string& objPath,
             const std::string& versionString, VersionPurpose versionPurpose,
-            const std::string& extVersion, const std::string& filePath,
+            const std::string& extVersion, const std::string& relDate, 
+            const std::string& filePath,
             const std::vector<std::string>& compatibleNames, eraseFunc callback,
             const std::string& id) :
         VersionInherit(bus, (objPath).c_str(),
@@ -91,6 +95,7 @@ class Version : public VersionInherit
     {
         // Set properties.
         extendedVersion(extVersion);
+        releaseDate(relDate);
         purpose(versionPurpose);
         version(versionString);
         path(filePath);
@@ -150,6 +155,17 @@ class Version : public VersionInherit
     static std::string
         getBMCExtendedVersion(const std::string& releaseFilePath);
 
+    /**
+     * @brief Get the BMC Release Date string.
+     *
+     * @param[in] releaseFilePath - The path to the file which contains
+     *                              the release machine string.
+     *
+     * @return The release date string.
+     */
+    static std::string
+        getBMCReleaseDate(const std::string& releaseFilePath);
+
     /**
      * @brief Get the active BMC version string.
      *
-- 
2.25.1

