Get PSU version from vendor specific tool

The code was getting the version from PSU inventory object.
This commit changes the behavior to use a vendor-specific tool to get
the version directly, where the tool is expected to be configured during
build time.

Add an example get_version app that shows the expected behavior of the
tool:
* It accepts an argument of PSU inventory object;
* It outputs the version to stdout.

Tested: 1. Put and configure to use the example get_version on witherspoon,
        verify that PSU software objects are created with the version
        returned by the exmaple tool.
        2. With the Witherspoon specific tool in
        https://gerrit.openbmc-project.xyz/c/openbmc/witherspoon-pfault-analysis/+/24811,
        verify the version is correctly got from the PSU inventory path
        and the software objects are created.

Signed-off-by: Lei YU <mine260309@gmail.com>
Change-Id: I5195cb6fc8998a76b09abcfe0b107364cb180c01
diff --git a/src/utils.hpp b/src/utils.hpp
index dd1317f..86ee5dd 100644
--- a/src/utils.hpp
+++ b/src/utils.hpp
@@ -63,6 +63,14 @@
  */
 std::string getVersionId(const std::string& version);
 
+/** @brief Get version of PSU specified by the inventory path
+ *
+ * @param[in] inventoryPath - The PSU inventory object path
+ *
+ * @return The version string, or empry string if it fails to get the version
+ */
+std::string getVersion(const std::string& inventoryPath);
+
 /**
  * @brief The interface for utils
  */
@@ -82,6 +90,8 @@
 
     virtual std::string getVersionId(const std::string& version) const = 0;
 
+    virtual std::string getVersion(const std::string& inventoryPath) const = 0;
+
     virtual any getPropertyImpl(sdbusplus::bus::bus& bus, const char* service,
                                 const char* path, const char* interface,
                                 const char* propertyName) const = 0;
@@ -109,6 +119,8 @@
 
     std::string getVersionId(const std::string& version) const override;
 
+    std::string getVersion(const std::string& inventoryPath) const override;
+
     any getPropertyImpl(sdbusplus::bus::bus& bus, const char* service,
                         const char* path, const char* interface,
                         const char* propertyName) const override;
@@ -130,6 +142,11 @@
     return getUtils().getVersionId(version);
 }
 
+inline std::string getVersion(const std::string& inventoryPath)
+{
+    return getUtils().getVersion(inventoryPath);
+}
+
 template <typename T>
 T getProperty(sdbusplus::bus::bus& bus, const char* service, const char* path,
               const char* interface, const char* propertyName)