vpd-tool --mfgClean implementation

vpd-tool supports a new option --mfgClean, which cleans specific
keywords in system backplane VPD and restore it with their default
value.

This option will be used to ensure that the VPD is properly defaulted
in the FRU stock.

The FAB test will make use this option to reset system
backplane VPD keywords to its defaults.

vpd-tool --mfgClean --yes

====================
Test:

./vpd-tool --mfgClean

This option resets some of the critical keywords in System Backplane VPD
to its default value. Do you really wish to proceed further?[yes/no]: yes

 The critical keywords from system backplane VPD has been reset successfully.

./vpd-tool --mfgClean --yes

 The critical keywords from system backplane VPD has been reset successfully.

Verified that the critical keywords have been reset to defaults.

Signed-off-by: Priyanga Ramasamy <priyanga24@in.ibm.com>
Change-Id: Ia53498d222f2828d07a7d170291e641b7f69f9ac
diff --git a/vpd_tool_impl.cpp b/vpd_tool_impl.cpp
index 6c32ec1..6244018 100644
--- a/vpd_tool_impl.cpp
+++ b/vpd_tool_impl.cpp
@@ -968,4 +968,70 @@
         }
 
     } while (true);
+}
+
+int VpdTool::cleanSystemVPD()
+{
+    try
+    {
+        // Get system VPD hardware data in map
+        unordered_map<string, DbusPropertyMap> vpdMap;
+        json js;
+        getVPDInMap(constants::systemVpdFilePath, vpdMap, js,
+                    constants::pimPath +
+                        static_cast<std::string>(constants::SYSTEM_OBJECT));
+
+        RecKwValMap kwdsToBeUpdated;
+
+        for (auto recordMap : svpdKwdMap)
+        {
+            const auto& record = recordMap.first;
+            std::unordered_map<std::string, Binary> kwDefault;
+            for (auto keywordMap : recordMap.second)
+            {
+                // Skip those keywords which cannot be reset at manufacturing
+                if (!std::get<3>(keywordMap))
+                {
+                    continue;
+                }
+                const auto& keyword = std::get<0>(keywordMap);
+
+                // Get hardware value for this keyword from vpdMap
+                Binary hardwareValue;
+
+                auto recItr = vpdMap.find(record);
+
+                if (recItr != vpdMap.end())
+                {
+                    DbusPropertyMap& kwValMap = recItr->second;
+                    auto kwItr = kwValMap.find(keyword);
+                    if (kwItr != kwValMap.end())
+                    {
+                        hardwareValue = toBinary(kwItr->second);
+                    }
+                }
+
+                // compare hardware value with the keyword's default value
+                auto defaultValue = std::get<1>(keywordMap);
+                if (hardwareValue != defaultValue)
+                {
+                    EditorImpl edit(constants::systemVpdFilePath, js, record,
+                                    keyword);
+                    edit.updateKeyword(defaultValue, 0, true);
+                }
+            }
+        }
+
+        std::cout
+            << "\n The critical keywords from system backplane VPD has been "
+               "reset successfully."
+            << std::endl;
+    }
+    catch (const std::exception& e)
+    {
+        std::cerr << e.what();
+        std::cerr
+            << "\nManufacturing reset on system vpd keywords is unsuccessful";
+    }
+    return 0;
 }
\ No newline at end of file