Retrieve FW version from IMG_BUILTIN_DIR

Added method to retrieve firmware level found in IMG_BUILTIN_DIR. This
is required behavior on some systems types.

Tested:
  Installed openbmc image on system and verified the function returns
  the version available in IMG_BUILT_DIR.

Change-Id: I10166a1412fb9de421bd304c40916a81c1ca0558
Signed-off-by: Faisal Awada <faisal@us.ibm.com>
diff --git a/meson.build b/meson.build
index a1e05d3..b575366 100644
--- a/meson.build
+++ b/meson.build
@@ -43,6 +43,8 @@
 cdata.set_quoted('IMG_DIR_PERSIST', get_option('IMG_DIR_PERSIST'))
 cdata.set_quoted('IMG_DIR_BUILTIN', get_option('IMG_DIR_BUILTIN'))
 
+cdata.set10('ALWAYS_USE_BUILTIN_IMG_DIR', get_option('ALWAYS_USE_BUILTIN_IMG_DIR'))
+
 phosphor_dbus_interfaces = dependency('phosphor-dbus-interfaces')
 phosphor_logging = dependency('phosphor-logging')
 sdbusplus = dependency('sdbusplus')
diff --git a/meson.options b/meson.options
index f37d08d..b5877c9 100644
--- a/meson.options
+++ b/meson.options
@@ -58,3 +58,8 @@
        type: 'string',
        value: '/usr/share/obmc/psu',
        description: 'The read-only directory where the built-in PSU images are stored')
+
+option('ALWAYS_USE_BUILTIN_IMG_DIR',
+    type: 'boolean',
+    value: false,
+    description: 'Only scan for PSU images in IMG_BUILTIN_DIR')
diff --git a/src/item_updater.cpp b/src/item_updater.cpp
index 4213f78..8e664b8 100644
--- a/src/item_updater.cpp
+++ b/src/item_updater.cpp
@@ -420,7 +420,10 @@
 {
     scanDirectory(IMG_DIR_BUILTIN);
 
-    scanDirectory(IMG_DIR_PERSIST);
+    if (!ALWAYS_USE_BUILTIN_IMG_DIR)
+    {
+        scanDirectory(IMG_DIR_PERSIST);
+    }
 }
 
 void ItemUpdater::scanDirectory(const fs::path& dir)
@@ -519,7 +522,15 @@
 
 std::optional<std::string> ItemUpdater::getLatestVersionId()
 {
-    auto latestVersion = utils::getLatestVersion(versionStrings);
+    std::string latestVersion;
+    if (ALWAYS_USE_BUILTIN_IMG_DIR)
+    {
+        latestVersion = getFWVersionFromBuiltinDir();
+    }
+    else
+    {
+        latestVersion = utils::getLatestVersion(versionStrings);
+    }
     if (latestVersion.empty())
     {
         return {};
@@ -646,6 +657,26 @@
     syncToLatestImage();
 }
 
+std::string ItemUpdater::getFWVersionFromBuiltinDir()
+{
+    std::string version;
+    for (const auto& activation : activations)
+    {
+        if (activation.second->path().starts_with(IMG_DIR_BUILTIN))
+        {
+            std::string versionId = activation.second->getVersionId();
+            auto it = versions.find(versionId);
+            if (it != versions.end())
+            {
+                const auto& versionPtr = it->second;
+                version = versionPtr->version();
+                break;
+            }
+        }
+    }
+    return version;
+}
+
 } // namespace updater
 } // namespace software
 } // namespace phosphor
diff --git a/src/item_updater.hpp b/src/item_updater.hpp
index bc8930e..e07aca8 100644
--- a/src/item_updater.hpp
+++ b/src/item_updater.hpp
@@ -201,6 +201,16 @@
      */
     void processPSUImageAndSyncToLatest();
 
+    /** @brief Retrieve FW version from IMG_DIR_BUILTIN
+     *
+     * This function retrieves the firmware version from the PSU model directory
+     * that is in the IMG_DIR_BUILTIN. It loops through the activations map to
+     * find matching path starts with IMG_DIR_BUILTIN, then gets the
+     * corresponding version ID, and then looks it up in the versions map to
+     * retrieve the associated version string.
+     */
+    std::string getFWVersionFromBuiltinDir();
+
     /** @brief Persistent sdbusplus D-Bus bus connection. */
     sdbusplus::bus_t& bus;