Enable redundant EEPROMs

This commit adds support in the VPD manager to
automatically update redundant EEPROMs.

The redundant EEPROMs path is obtained from the
"redundantEeprom" key in the VPD JSON.

Signed-off-by: Santosh Puranik <santosh.puranik@in.ibm.com>
Change-Id: I88dd6710523dd0d46d14bec5c849950db15cba28
diff --git a/vpd-manager/manager.cpp b/vpd-manager/manager.cpp
index 036f843..d391a0b 100644
--- a/vpd-manager/manager.cpp
+++ b/vpd-manager/manager.cpp
@@ -121,15 +121,23 @@
         for (const auto& itemEEPROM : groupEEPROM)
         {
             bool isMotherboard = false;
+            std::string redundantPath;
+
             if (itemEEPROM["extraInterfaces"].find(
                     "xyz.openbmc_project.Inventory.Item.Board.Motherboard") !=
                 itemEEPROM["extraInterfaces"].end())
             {
                 isMotherboard = true;
             }
-            frus.emplace(itemEEPROM["inventoryPath"]
-                             .get_ref<const nlohmann::json::string_t&>(),
-                         std::make_pair(itemFRUS.key(), isMotherboard));
+            if (itemEEPROM.find("redundantEeprom") != itemEEPROM.end())
+            {
+                redundantPath = itemEEPROM["redundantEeprom"]
+                                    .get_ref<const nlohmann::json::string_t&>();
+            }
+            frus.emplace(
+                itemEEPROM["inventoryPath"]
+                    .get_ref<const nlohmann::json::string_t&>(),
+                std::make_tuple(itemFRUS.key(), redundantPath, isMotherboard));
 
             if (itemEEPROM["extraInterfaces"].find(IBM_LOCATION_CODE_INF) !=
                 itemEEPROM["extraInterfaces"].end())
@@ -168,14 +176,35 @@
             throw std::runtime_error("Inventory path not found");
         }
 
-        inventory::Path vpdFilePath = frus.find(objPath)->second.first;
+        inventory::Path vpdFilePath = std::get<0>(frus.find(objPath)->second);
 
         // instantiate editor class to update the data
         EditorImpl edit(vpdFilePath, jsonFile, recordName, keyword, objPath);
-        edit.updateKeyword(value, true);
+
+        uint32_t offset = 0;
+        // Setup offset, if any
+        for (const auto& item : jsonFile["frus"][vpdFilePath])
+        {
+            if (item.find("offset") != item.end())
+            {
+                offset = item["offset"];
+                break;
+            }
+        }
+
+        edit.updateKeyword(value, offset, true);
+
+        // If we have a redundant EEPROM to update, then update just the EEPROM,
+        // not the cache since that is already done when we updated the primary
+        if (!std::get<1>(frus.find(objPath)->second).empty())
+        {
+            EditorImpl edit(std::get<1>(frus.find(objPath)->second), jsonFile,
+                            recordName, keyword);
+            edit.updateKeyword(value, offset, false);
+        }
 
         // if it is a motehrboard FRU need to check for location expansion
-        if (frus.find(objPath)->second.second)
+        if (std::get<2>(frus.find(objPath)->second))
         {
             if (recordName == "VCEN" && (keyword == "FC" || keyword == "SE"))
             {