IBM VPD Parser support for both 2U & 4U system

Based on motherboard IM keyword the type of the system is identified
and the corresponding json is linked at the runtime.

Currently 2U system has support for single dasd-backplane
whereas 4U system has support for more than one dasd-backplanes.

Tested on simics.

Change-Id: Ia3eb48661fe565f6286c079a8f87736bb136210a
Signed-off-by: Priyanga Ramasamy <priyanga24@in.ibm.com>
diff --git a/ibm_vpd_app.cpp b/ibm_vpd_app.cpp
index 4c3aba4..9022e3d 100644
--- a/ibm_vpd_app.cpp
+++ b/ibm_vpd_app.cpp
@@ -9,6 +9,7 @@
 #include <CLI/CLI.hpp>
 #include <algorithm>
 #include <exception>
+#include <filesystem>
 #include <fstream>
 #include <iostream>
 #include <iterator>
@@ -19,6 +20,9 @@
 using namespace CLI;
 using namespace vpd::keyword::parser;
 using namespace vpdFormat;
+using namespace openpower::vpd::constants;
+namespace fs = filesystem;
+using json = nlohmann::json;
 
 /**
  * @brief Expands location codes
@@ -345,6 +349,51 @@
 
     if (isSystemVpd)
     {
+        vector<uint8_t> imVal;
+        if constexpr (is_same<T, Parsed>::value)
+        {
+            auto property = vpdMap.find("VSBP");
+            if (property != vpdMap.end())
+            {
+                auto value = (property->second).find("IM");
+                if (value != (property->second).end())
+                {
+                    copy(value->second.begin(), value->second.end(),
+                         back_inserter(imVal));
+                }
+            }
+        }
+
+        fs::path target;
+        fs::path link = INVENTORY_JSON_SYM_LINK;
+
+        ostringstream oss;
+        for (auto& i : imVal)
+        {
+            oss << setw(2) << setfill('0') << hex << static_cast<int>(i);
+        }
+        string imValStr = oss.str();
+
+        if (imValStr == SYSTEM_4U) // 4U
+        {
+            target = INVENTORY_JSON_4U;
+        }
+
+        else if (imValStr == SYSTEM_2U) // 2U
+        {
+            target = INVENTORY_JSON_2U;
+        }
+
+        // unlink the symlink which is created at build time
+        remove(INVENTORY_JSON_SYM_LINK);
+        // create a new symlink based on the system
+        fs::create_symlink(target, link);
+
+        // Reloading the json
+        ifstream inventoryJson(link);
+        auto js = json::parse(inventoryJson);
+        inventoryJson.close();
+
         inventory::ObjectMap primeObject = primeInventory(js, vpdMap);
         objects.insert(primeObject.begin(), primeObject.end());
     }
@@ -359,8 +408,6 @@
 
     try
     {
-        using json = nlohmann::json;
-
         App app{"ibm-read-vpd - App to read IPZ format VPD, parse it and store "
                 "in DBUS"};
         string file{};