Support XYZ interface for Location code

Update xyz interface for Location code in ibm-read-parser and vpd-manager
along with com.ibm.path for Location code.

Test Result-
busctl introspect xyz.openbmc_project.Inventory.Manager  /xyz/openbmc_project/inventory/system/chassis/motherboard| grep -e "Location" -e "FC" -e "SE"
com.ibm.ipzvpd.Location                              interface -         -                                        -
.LocationCode                                        property  s         "U78DA.ND1.WZS004K-P0"                   emits-change writable
.FC                                                  property  ay        8 65 65 68 65 45 48 48 49                emits-change writable
.SE                                                  property  ay        7 68 68 83 48 48 52 75                   emits-change writable
.SE                                                  property  ay        7 49 51 57 70 50 66 48                   emits-change writable
xyz.openbmc_project.Inventory.Decorator.LocationCode interface -         -                                        -
.LocationCode                                        property  s         "UAADA.ND0.DDS004K-P0"                   emits-change writable

Below write command should trigger the LC update for motherboard and other dependent FRUs.

busctl call com.ibm.VPD.Manager /com/ibm/VPD/Manager com.ibm.VPD.Manager WriteKeyword ossay  "/system/chassis/motherboard" "VCEN" "FC" 2 55 56
busctl call com.ibm.VPD.Manager /com/ibm/VPD/Manager com.ibm.VPD.Manager WriteKeyword ossay  "/system/chassis/motherboard" "VCEN" "SE" 2 87 90

busctl introspect xyz.openbmc_project.Inventory.Manager  /xyz/openbmc_project/inventory/system/chassis/motherboard| grep -e "Location" -e "FC" -e "SE"
com.ibm.ipzvpd.Location                              interface -         -                                        -
.LocationCode                                        property  s         "U78DA.ND0.WZS004K-P0"                   emits-change writable
.FC                                                  property  ay        8 55 56 68 65 45 48 48 49                emits-change writable
.SE                                                  property  ay        7 87 90 83 48 48 52 75                   emits-change writable
.SE                                                  property  ay        7 49 51 57 70 50 66 48                   emits-change writable
xyz.openbmc_project.Inventory.Decorator.LocationCode interface -         -                                        -
.LocationCode                                        property  s         "U78DA.ND0.WZS004K-P0"                   emits-change writable

busctl introspect xyz.openbmc_project.Inventory.Manager  /xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0| grep -e "Location" -e "FC" -e "SE"
com.ibm.ipzvpd.Location                              interface -         -                                        -
.LocationCode                                        property  s         "U78DA.ND0.WZS004K-P0-C15"               emits-change writable
xyz.openbmc_project.Inventory.Decorator.LocationCode interface -         -                                        -
.LocationCode                                        property  s         "U78DA.ND0.WZS004K-P0-C15"               emits-change writable

Change-Id: If8715b8cafcc87d8a46e7083f90f162c5ad4a6b0
Signed-off-by: Alpana Kumari <alpankum@in.ibm.com>
diff --git a/const.hpp b/const.hpp
index 69c8107..6ab10e5 100644
--- a/const.hpp
+++ b/const.hpp
@@ -39,7 +39,9 @@
 static constexpr auto MB_HOUR_END = 13;
 static constexpr auto MB_MIN_END = 16;
 static constexpr auto SYSTEM_OBJECT = "/system/chassis/motherboard";
-static constexpr auto LOCATION_CODE_INF = "com.ibm.ipzvpd.Location";
+static constexpr auto IBM_LOCATION_CODE_INF = "com.ibm.ipzvpd.Location";
+static constexpr auto XYZ_LOCATION_CODE_INF =
+    "xyz.openbmc_project.Inventory.Decorator.LocationCode";
 constexpr int IPZ_DATA_START = 11;
 constexpr uint8_t KW_VAL_PAIR_START_TAG = 0x84;
 constexpr uint8_t RECORD_END_TAG = 0x78;
diff --git a/ibm_vpd_app.cpp b/ibm_vpd_app.cpp
index fed83ad..a678adb 100644
--- a/ibm_vpd_app.cpp
+++ b/ibm_vpd_app.cpp
@@ -207,11 +207,13 @@
                 if constexpr (is_same<T, Parsed>::value)
                 {
                     if (busProp == "LocationCode" &&
-                        inf == "com.ibm.ipzvpd.Location")
+                        inf == IBM_LOCATION_CODE_INF)
                     {
+                        // TODO deprecate the com.ibm interface later
                         auto prop = expandLocationCode(
                             itr.value().get<string>(), vpdMap, isSystemVpd);
                         props.emplace(busProp, prop);
+                        interfaces.emplace(XYZ_LOCATION_CODE_INF, props);
                     }
                     else
                     {
@@ -443,8 +445,7 @@
                     for (const auto& eI : itemEEPROM["extraInterfaces"].items())
                     {
                         inventory::PropertyMap props;
-                        if (eI.key() ==
-                            openpower::vpd::constants::LOCATION_CODE_INF)
+                        if (eI.key() == IBM_LOCATION_CODE_INF)
                         {
                             if constexpr (std::is_same<T, Parsed>::value)
                             {
diff --git a/test/vpd-manager-test/editor_test.cpp b/test/vpd-manager-test/editor_test.cpp
index 1549df8..de7e2ba 100644
--- a/test/vpd-manager-test/editor_test.cpp
+++ b/test/vpd-manager-test/editor_test.cpp
@@ -69,8 +69,9 @@
         for (const auto& itemEEPROM : groupEEPROM)
         {
             fruLocationCode.emplace(
-                itemEEPROM["extraInterfaces"][LOCATION_CODE_INF]["LocationCode"]
-                    .get_ref<const nlohmann::json::string_t&>(),
+                itemEEPROM["extraInterfaces"][IBM_LOCATION_CODE_INF]
+                          ["LocationCode"]
+                              .get_ref<const nlohmann::json::string_t&>(),
                 itemEEPROM["inventoryPath"]
                     .get_ref<const nlohmann::json::string_t&>());
         }
diff --git a/test/vpd-manager-test/reader_test.cpp b/test/vpd-manager-test/reader_test.cpp
index b6cf80c..58d8d2f 100644
--- a/test/vpd-manager-test/reader_test.cpp
+++ b/test/vpd-manager-test/reader_test.cpp
@@ -65,8 +65,9 @@
         for (const auto& itemEEPROM : groupEEPROM)
         {
             fruLocationCode.emplace(
-                itemEEPROM["extraInterfaces"][LOCATION_CODE_INF]["LocationCode"]
-                    .get_ref<const nlohmann::json::string_t&>(),
+                itemEEPROM["extraInterfaces"][IBM_LOCATION_CODE_INF]
+                          ["LocationCode"]
+                              .get_ref<const nlohmann::json::string_t&>(),
                 itemEEPROM["inventoryPath"]
                     .get_ref<const nlohmann::json::string_t&>());
         }
@@ -109,8 +110,8 @@
 {
     // mock the call to read bus property
     MockUtilCalls uCalls;
-    EXPECT_CALL(uCalls, readBusProperty("/system/chassis/motherboard",
-                                        LOCATION_CODE_INF, "LocationCode"))
+    EXPECT_CALL(uCalls, readBusProperty(SYSTEM_OBJECT, IBM_LOCATION_CODE_INF,
+                                        "LocationCode"))
         .Times(1)
         .WillOnce(testing::Return("U78DA.ND1.1234567-P0"));
 
diff --git a/vpd-manager/editor_impl.cpp b/vpd-manager/editor_impl.cpp
index df1441c..091d026 100644
--- a/vpd-manager/editor_impl.cpp
+++ b/vpd-manager/editor_impl.cpp
@@ -2,6 +2,7 @@
 
 #include "editor_impl.hpp"
 
+#include "common_utility.hpp"
 #include "ibm_vpd_utils.hpp"
 #include "ipz_parser.hpp"
 #include "parser_factory.hpp"
@@ -293,6 +294,7 @@
 
 void EditorImpl::processAndUpdateCI(const std::string& objectPath)
 {
+    inventory::ObjectMap objects;
     for (auto& commonInterface : jsonFile["commonInterfaces"].items())
     {
         for (auto& ciPropertyList : commonInterface.value().items())
@@ -305,21 +307,26 @@
                     (ciPropertyList.value().value("keywordName", "") ==
                      thisRecord.recKWd))
                 {
+                    inventory::PropertyMap prop;
+                    inventory::InterfaceMap interfaces;
                     std::string kwdData(thisRecord.kwdUpdatedData.begin(),
                                         thisRecord.kwdUpdatedData.end());
 
-                    makeDbusCall<std::string>((INVENTORY_PATH + objectPath),
-                                              commonInterface.key(),
-                                              ciPropertyList.key(), kwdData);
+                    prop.emplace(ciPropertyList.key(), move(kwdData));
+                    interfaces.emplace(commonInterface.key(), move(prop));
+                    objects.emplace(objectPath, move(interfaces));
                 }
             }
         }
     }
+    // Notify PIM
+    common::utility::callPIM(move(objects));
 }
 
 void EditorImpl::processAndUpdateEI(const nlohmann::json& Inventory,
                                     const inventory::Path& objPath)
 {
+    inventory::ObjectMap objects;
     for (const auto& extraInterface : Inventory["extraInterfaces"].items())
     {
         if (extraInterface.value() != NULL)
@@ -334,18 +341,23 @@
                         ((eiPropertyList.value().value("keywordName", "") ==
                           thisRecord.recKWd)))
                     {
+                        inventory::PropertyMap prop;
+                        inventory::InterfaceMap interfaces;
                         std::string kwdData(thisRecord.kwdUpdatedData.begin(),
                                             thisRecord.kwdUpdatedData.end());
-                        makeDbusCall<std::string>(
-                            (INVENTORY_PATH + objPath), extraInterface.key(),
-                            eiPropertyList.key(),
-                            encodeKeyword(kwdData, eiPropertyList.value().value(
-                                                       "encoding", "")));
+                        encodeKeyword(kwdData, eiPropertyList.value().value(
+                                                   "encoding", ""));
+
+                        prop.emplace(eiPropertyList.key(), move(kwdData));
+                        interfaces.emplace(extraInterface.key(), move(prop));
+                        objects.emplace(objPath, move(interfaces));
                     }
                 }
             }
         }
     }
+    // Notify PIM
+    common::utility::callPIM(move(objects));
 }
 
 void EditorImpl::updateCache()
@@ -353,9 +365,12 @@
     const std::vector<nlohmann::json>& groupEEPROM =
         jsonFile["frus"][vpdFilePath].get_ref<const nlohmann::json::array_t&>();
 
+    inventory::ObjectMap objects;
     // iterate through all the inventories for this file path
     for (const auto& singleInventory : groupEEPROM)
     {
+        inventory::PropertyMap prop;
+        inventory::InterfaceMap interfaces;
         // by default inherit property is true
         bool isInherit = true;
         bool isInheritEI = true;
@@ -386,11 +401,13 @@
             // For CPU- update  com interface only when isCI true
             if ((!isCpuModuleOnly) || (isCpuModuleOnly && isCI))
             {
-                makeDbusCall<Binary>(
-                    (INVENTORY_PATH +
-                     singleInventory["inventoryPath"].get<std::string>()),
+                prop.emplace(thisRecord.recKWd, thisRecord.kwdUpdatedData);
+                interfaces.emplace(
                     (IPZ_INTERFACE + (std::string) "." + thisRecord.recName),
-                    thisRecord.recKWd, thisRecord.kwdUpdatedData);
+                    move(prop));
+                objects.emplace(
+                    (singleInventory["inventoryPath"].get<std::string>()),
+                    move(interfaces));
             }
 
             // process Common interface
@@ -402,11 +419,13 @@
         {
             if (isCpuModuleOnly)
             {
-                makeDbusCall<Binary>(
-                    (INVENTORY_PATH +
-                     singleInventory["inventoryPath"].get<std::string>()),
+                prop.emplace(thisRecord.recKWd, thisRecord.kwdUpdatedData);
+                interfaces.emplace(
                     (IPZ_INTERFACE + (std::string) "." + thisRecord.recName),
-                    thisRecord.recKWd, thisRecord.kwdUpdatedData);
+                    move(prop));
+                objects.emplace(
+                    (singleInventory["inventoryPath"].get<std::string>()),
+                    move(interfaces));
             }
 
             // process extra interfaces
@@ -415,6 +434,8 @@
                                    .get_ref<const nlohmann::json::string_t&>());
         }
     }
+    // Notify PIM
+    common::utility::callPIM(move(objects));
 }
 
 void EditorImpl::expandLocationCode(const std::string& locationCodeType)
@@ -439,28 +460,35 @@
 
     const nlohmann::json& groupFRUS =
         jsonFile["frus"].get_ref<const nlohmann::json::object_t&>();
+    inventory::ObjectMap objects;
+
     for (const auto& itemFRUS : groupFRUS.items())
     {
         const std::vector<nlohmann::json>& groupEEPROM =
             itemFRUS.value().get_ref<const nlohmann::json::array_t&>();
         for (const auto& itemEEPROM : groupEEPROM)
         {
+            inventory::PropertyMap prop;
+            inventory::InterfaceMap interfaces;
+            const auto& objectPath = itemEEPROM["inventoryPath"];
+            sdbusplus::message::object_path object(objectPath);
+
             // check if the given item implements location code interface
-            if (itemEEPROM["extraInterfaces"].find(LOCATION_CODE_INF) !=
+            if (itemEEPROM["extraInterfaces"].find(IBM_LOCATION_CODE_INF) !=
                 itemEEPROM["extraInterfaces"].end())
             {
                 const std::string& unexpandedLocationCode =
-                    itemEEPROM["extraInterfaces"][LOCATION_CODE_INF]
+                    itemEEPROM["extraInterfaces"][IBM_LOCATION_CODE_INF]
                               ["LocationCode"]
                                   .get_ref<const nlohmann::json::string_t&>();
                 std::size_t idx = unexpandedLocationCode.find(locationCodeType);
                 if (idx != std::string::npos)
                 {
-                    std::string expandedLoctionCode(unexpandedLocationCode);
+                    std::string expandedLocationCode(unexpandedLocationCode);
 
                     if (locationCodeType == "fcs")
                     {
-                        expandedLoctionCode.replace(
+                        expandedLocationCode.replace(
                             idx, 3,
                             propertyFCorTM.substr(0, 4) + ".ND0." + propertySE);
                     }
@@ -468,20 +496,22 @@
                     {
                         std::replace(propertyFCorTM.begin(),
                                      propertyFCorTM.end(), '-', '.');
-                        expandedLoctionCode.replace(
+                        expandedLocationCode.replace(
                             idx, 3, propertyFCorTM + "." + propertySE);
                     }
 
-                    // update the DBUS interface
-                    makeDbusCall<std::string>(
-                        (INVENTORY_PATH +
-                         itemEEPROM["inventoryPath"]
-                             .get_ref<const nlohmann::json::string_t&>()),
-                        LOCATION_CODE_INF, "LocationCode", expandedLoctionCode);
+                    // update the DBUS interface COM as well as XYZ path
+                    prop.emplace("LocationCode", expandedLocationCode);
+                    // TODO depricate this com.ibm interface later
+                    interfaces.emplace(IBM_LOCATION_CODE_INF, prop);
+                    interfaces.emplace(XYZ_LOCATION_CODE_INF, move(prop));
                 }
             }
+            objects.emplace(move(object), move(interfaces));
         }
     }
+    // Notify PIM
+    common::utility::callPIM(move(objects));
 }
 
 string EditorImpl::getSysPathForThisFruType(const string& moduleObjPath,
diff --git a/vpd-manager/manager.cpp b/vpd-manager/manager.cpp
index 42b1bbd..829dce8 100644
--- a/vpd-manager/manager.cpp
+++ b/vpd-manager/manager.cpp
@@ -87,11 +87,11 @@
                              .get_ref<const nlohmann::json::string_t&>(),
                          std::make_pair(itemFRUS.key(), isMotherboard));
 
-            if (itemEEPROM["extraInterfaces"].find(LOCATION_CODE_INF) !=
+            if (itemEEPROM["extraInterfaces"].find(IBM_LOCATION_CODE_INF) !=
                 itemEEPROM["extraInterfaces"].end())
             {
                 fruLocationCode.emplace(
-                    itemEEPROM["extraInterfaces"][LOCATION_CODE_INF]
+                    itemEEPROM["extraInterfaces"][IBM_LOCATION_CODE_INF]
                               ["LocationCode"]
                                   .get_ref<const nlohmann::json::string_t&>(),
                     itemEEPROM["inventoryPath"]
diff --git a/vpd-manager/reader_impl.cpp b/vpd-manager/reader_impl.cpp
index 08eb32b..b1f16b1 100644
--- a/vpd-manager/reader_impl.cpp
+++ b/vpd-manager/reader_impl.cpp
@@ -75,7 +75,7 @@
     utility utilObj;
 #endif
     expandedLocationCode = utilObj.readBusProperty(
-        iterator->second, LOCATION_CODE_INF, "LocationCode");
+        iterator->second, IBM_LOCATION_CODE_INF, "LocationCode");
     return expandedLocationCode;
 }