API to check powerVS configuration

The commit implements change to check for powerVS configuration.

It is a combination of system series and driver running on the system.
Once that is established, only after that VPD vpdate will take place
w.r.t powerVS system.

Change-Id: I93fefcb79ced4f89bd6f5143666b4cd487897ac8
Signed-off-by: Sunny Srivastava <sunnsr25@in.ibm.com>
diff --git a/vpd-manager/include/utility/dbus_utility.hpp b/vpd-manager/include/utility/dbus_utility.hpp
index d13e123..344a637 100644
--- a/vpd-manager/include/utility/dbus_utility.hpp
+++ b/vpd-manager/include/utility/dbus_utility.hpp
@@ -1,6 +1,7 @@
 #pragma once
 
 #include "constants.hpp"
+#include "exceptions.hpp"
 #include "logger.hpp"
 #include "types.hpp"
 
@@ -607,5 +608,82 @@
 
     return *l_imValue;
 }
+
+/**
+ * @brief API to return prefix of functional firmware image.
+ *
+ * Every functional image belongs to a series which is denoted by the first two
+ * characters of the image name. The API extracts that and returns it to the
+ * caller.
+ *
+ * @return Two character string, empty string in case of any error.
+ */
+inline std::string getImagePrefix()
+{
+    try
+    {
+        types::DbusVariantType l_retVal = readDbusProperty(
+            constants::objectMapperService, constants::functionalImageObjPath,
+            constants::associationInterface, "endpoints");
+
+        auto l_listOfFunctionalPath =
+            std::get_if<std::vector<std::string>>(&l_retVal);
+
+        if (!l_listOfFunctionalPath || (*l_listOfFunctionalPath).empty())
+        {
+            throw DbusException("failed to get functional image path.");
+        }
+
+        for (const auto& l_imagePath : *l_listOfFunctionalPath)
+        {
+            types::DbusVariantType l_retValPriority =
+                readDbusProperty(constants::imageUpdateService, l_imagePath,
+                                 constants::imagePrirotyInf, "Priority");
+
+            auto l_imagePriority = std::get_if<uint8_t>(&l_retValPriority);
+            if (!l_imagePriority)
+            {
+                throw DbusException(
+                    "failed to read functional image priority for path [" +
+                    l_imagePath + "]");
+            }
+
+            // only interested in running image.
+            if (*l_imagePriority != constants::VALUE_0)
+            {
+                continue;
+            }
+
+            types::DbusVariantType l_retExVer = readDbusProperty(
+                constants::imageUpdateService, l_imagePath,
+                constants::imageExtendedVerInf, "ExtendedVersion");
+
+            auto l_imageExtendedVersion = std::get_if<std::string>(&l_retExVer);
+            if (!l_imageExtendedVersion)
+            {
+                throw DbusException(
+                    "Unable to read extended version for the functional image [" +
+                    l_imagePath + "]");
+            }
+
+            if ((*l_imageExtendedVersion).empty() ||
+                (*l_imageExtendedVersion).length() <= constants::VALUE_2)
+            {
+                throw DbusException("Invalid extended version read for path [" +
+                                    l_imagePath + "]");
+            }
+
+            // return first two character from image name.
+            return (*l_imageExtendedVersion)
+                .substr(constants::VALUE_0, constants::VALUE_2);
+        }
+        throw std::runtime_error("No Image found with required priority.");
+    }
+    catch (const std::exception& l_ex)
+    {
+        logging::logMessage(l_ex.what());
+        return std::string{};
+    }
+}
 } // namespace dbusUtility
 } // namespace vpd