PLDM: Send firmware version to Hostboot

This commit sends the firmware version by adding
the version field in the General Fru record.

Tested on rainier using pldmtool

root@rainier:/tmp# ./pldmtool fru GetFruRecordTable
Received Msg
Buffer Data: 08 01 80 04 02 00 00 00 00 05
Sending Msg
Buffer Data: 00 04 02 00 00 00 00 00 05 01 00 01 03 01 02 08 39 31 30 35 2d 32 32 41 04 07 53 49 4d 50 31 30 52 0a 1b 66 77 31 30 32 30 2e 30 30 2d 38 2e 34 2d 30 2d 67 35 63 63 66 35 38 64 61 38 66 01 00 01 02 01 02
.......
Received Msg
Buffer Data: 08 01 00 04 02 00 00 00 00 00 05 01 00 01 03 01 02 08 39 31 30 35 2d 32 32 41 04 07 53 49 4d 50 31 30 52 0a 1b 66 77 31 30 32 30 2e 30 30 2d 38 2e 34 2d 30 2d 67 35 63 63 66 35 38 64 61 38 66 01 00 01 02 01 02 08 39 31 30 35 2d.........
 [
        {
            "FRU Record Set Identifier": 1,
            "FRU Record Type": "General(1)",
            "Number of FRU fields": 3,
            "Encoding Type for FRU fields": "ASCII(1)"
        },
        {
            "FRU Field Type": "Model(2)",
            "FRU Field Length": 8,
            "FRU Field Value": "9105-22A"
        },
        {
            "FRU Field Type": "Serial Number(4)",
            "FRU Field Length": 7,
            "FRU Field Value": "SIMP10R"
        },
        {
            "FRU Field Type": "Version(10)",
            "FRU Field Length": 27,
            "FRU Field Value": "fw1020.00-8.4-0-g5ccf58da8f"
        }
    ],
.........

Change-Id: Ib14b122ec7cc1e68df3e41a7c61276f76803e681
Signed-off-by: Pavithra Barithaya <pavithra.b@ibm.com>
diff --git a/common/utils.hpp b/common/utils.hpp
index 4e702d8..7478aab 100644
--- a/common/utils.hpp
+++ b/common/utils.hpp
@@ -121,6 +121,7 @@
 }
 
 constexpr auto dbusProperties = "org.freedesktop.DBus.Properties";
+constexpr auto mapperService = "xyz.openbmc_project.ObjectMapper";
 
 struct DBusMapping
 {
diff --git a/libpldm/entity.h b/libpldm/entity.h
index fe7ac80..600946e 100644
--- a/libpldm/entity.h
+++ b/libpldm/entity.h
@@ -136,6 +136,9 @@
 	PLDM_ENTITY_INTERCONNECT = 188,

 	PLDM_ENTITY_PLUG = 189,

 	PLDM_ENTITY_SOCKET = 190,

+

+	/* Logical */

+	PLDM_ENTITY_SYSTEM_LOGICAL = 11521,

 };

 

 #ifdef __cplusplus

diff --git a/libpldmresponder/fru.cpp b/libpldmresponder/fru.cpp
index 2555a97..1c04a12 100644
--- a/libpldmresponder/fru.cpp
+++ b/libpldmresponder/fru.cpp
@@ -1,5 +1,6 @@
 #include "fru.hpp"
 
+#include "libpldm/entity.h"
 #include "libpldm/utils.h"
 
 #include "common/utils.hpp"
@@ -120,7 +121,36 @@
     }
     isBuilt = true;
 }
-
+std::string FruImpl::populatefwVersion()
+{
+    static constexpr auto fwFunctionalObjPath =
+        "/xyz/openbmc_project/software/functional";
+    auto& bus = pldm::utils::DBusHandler::getBus();
+    std::string currentBmcVersion;
+    try
+    {
+        auto method =
+            bus.new_method_call(pldm::utils::mapperService, fwFunctionalObjPath,
+                                pldm::utils::dbusProperties, "Get");
+        method.append("xyz.openbmc_project.Association", "endpoints");
+        std::variant<std::vector<std::string>> paths;
+        auto reply = bus.call(method);
+        reply.read(paths);
+        auto fwRunningVersion = std::get<std::vector<std::string>>(paths)[0];
+        constexpr auto versionIntf = "xyz.openbmc_project.Software.Version";
+        auto version = pldm::utils::DBusHandler().getDbusPropertyVariant(
+            fwRunningVersion.c_str(), "Version", versionIntf);
+        currentBmcVersion = std::get<std::string>(version);
+    }
+    catch (const std::exception& e)
+    {
+        std::cerr << "failed to make a d-bus call "
+                     "Asociation, ERROR= "
+                  << e.what() << "\n";
+        return {};
+    }
+    return currentBmcVersion;
+}
 void FruImpl::populateRecords(
     const pldm::responder::dbus::InterfaceMap& interfaces,
     const fru_parser::FruRecordInfos& recordInfos, const pldm_entity& entity)
@@ -136,9 +166,19 @@
         uint8_t numFRUFields = 0;
         for (auto const& [intf, prop, propType, fieldTypeNum] : fieldInfos)
         {
+
             try
             {
-                auto propValue = interfaces.at(intf).at(prop);
+                pldm::responder::dbus::Value propValue;
+                if (entity.entity_type == PLDM_ENTITY_SYSTEM_LOGICAL &&
+                    prop == "Version")
+                {
+                    propValue = populatefwVersion();
+                }
+                else
+                {
+                    propValue = interfaces.at(intf).at(prop);
+                }
                 if (propType == "bytearray")
                 {
                     auto byteArray = std::get<std::vector<uint8_t>>(propValue);
diff --git a/libpldmresponder/fru.hpp b/libpldmresponder/fru.hpp
index c890a87..5ae593a 100644
--- a/libpldmresponder/fru.hpp
+++ b/libpldmresponder/fru.hpp
@@ -137,6 +137,12 @@
         return associatedEntityMap;
     }
 
+    /* @brief Method to populate the firmware version ID
+     *
+     * @return firmware version ID
+     */
+    std::string populatefwVersion();
+
   private:
     uint16_t nextRSI()
     {