API to read IM value from system planar

This commit implements an API to read IM value from system planar using
the IM keyword offset value.

Change-Id: I69f48895aa814e31a4ce23bcf4f8aa954449c969
Signed-off-by: Anupama B R <anupama.b.r1@ibm.com>
diff --git a/vpd-manager/include/single_fab.hpp b/vpd-manager/include/single_fab.hpp
index 03c6cee..8587519 100644
--- a/vpd-manager/include/single_fab.hpp
+++ b/vpd-manager/include/single_fab.hpp
@@ -22,5 +22,12 @@
      * @return IM value on success, empty string otherwise.
      */
     std::string getImFromPersistedLocation() const noexcept;
+
+    /**
+     * @brief API to get IM value from system planar EEPROM path.
+     *
+     * @return IM value on success, empty string otherwise.
+     */
+    std::string getImFromPlanar() const noexcept;
 };
 } // namespace vpd
diff --git a/vpd-manager/src/single_fab.cpp b/vpd-manager/src/single_fab.cpp
index 9b2045c..24556d0 100644
--- a/vpd-manager/src/single_fab.cpp
+++ b/vpd-manager/src/single_fab.cpp
@@ -1,3 +1,5 @@
+#include "config.h"
+
 #include "single_fab.hpp"
 
 #include "constants.hpp"
@@ -9,6 +11,8 @@
 {
 constexpr auto pimPersistVsbpPath =
     "/var/lib/phosphor-inventory-manager/xyz/openbmc_project/inventory/system/chassis/motherboard/com.ibm.ipzvpd.VSBP";
+constexpr auto IM_SIZE_IN_BYTES = 0x04;
+constexpr auto IM_KW_VALUE_OFFSET = 0x000005fb;
 
 std::string SingleFab::getImFromPersistedLocation() const noexcept
 {
@@ -46,4 +50,39 @@
 
     return std::string();
 }
+
+std::string SingleFab::getImFromPlanar() const noexcept
+{
+    try
+    {
+        types::BinaryVector l_imValue(IM_SIZE_IN_BYTES);
+        std::fstream l_vpdFileStream;
+
+        l_vpdFileStream.exceptions(
+            std::ifstream::badbit | std::ifstream::failbit);
+
+        l_vpdFileStream.open(SYSTEM_VPD_FILE_PATH,
+                             std::ios::in | std::ios::binary);
+
+        l_vpdFileStream.seekg(IM_KW_VALUE_OFFSET, std::ios_base::beg);
+
+        // Read keyword value
+        l_vpdFileStream.read(reinterpret_cast<char*>(&l_imValue[0]),
+                             IM_SIZE_IN_BYTES);
+
+        l_vpdFileStream.clear(std::ios_base::eofbit);
+
+        std::ostringstream l_imData;
+        for (const auto& l_byte : l_imValue)
+        {
+            l_imData << std::setw(2) << std::setfill('0') << std::hex
+                     << static_cast<int>(l_byte);
+        }
+        return l_imData.str();
+    }
+    catch (const std::ifstream::failure& l_ex)
+    {}
+
+    return std::string();
+}
 } // namespace vpd