Move preAction postAction to Util

This commit moves  preAction and postFailAction to ibm_read_util,
as we need them as common utility functions, to use it in vpd manager.

Signed-off-by: Alpana Kumari <alpankum@in.ibm.com>
Change-Id: Iaade31143b8f114a9adec82a5c4d6ae4e9e2a2d5
diff --git a/ibm_vpd_utils.cpp b/ibm_vpd_utils.cpp
index 12c9a2d..2690c26 100644
--- a/ibm_vpd_utils.cpp
+++ b/ibm_vpd_utils.cpp
@@ -8,6 +8,7 @@
 
 #include <filesystem>
 #include <fstream>
+#include <gpiod.hpp>
 #include <iomanip>
 #include <nlohmann/json.hpp>
 #include <phosphor-logging/elog-errors.hpp>
@@ -613,6 +614,140 @@
     return str;
 }
 
+void executePostFailAction(const nlohmann::json& json, const string& file)
+{
+    if ((json["frus"][file].at(0)).find("postActionFail") ==
+        json["frus"][file].at(0).end())
+    {
+        return;
+    }
+
+    uint8_t pinValue = 0;
+    string pinName;
+
+    for (const auto& postAction :
+         (json["frus"][file].at(0))["postActionFail"].items())
+    {
+        if (postAction.key() == "pin")
+        {
+            pinName = postAction.value();
+        }
+        else if (postAction.key() == "value")
+        {
+            // Get the value to set
+            pinValue = postAction.value();
+        }
+    }
+
+    cout << "Setting GPIO: " << pinName << " to " << (int)pinValue << endl;
+
+    try
+    {
+        gpiod::line outputLine = gpiod::find_line(pinName);
+
+        if (!outputLine)
+        {
+            cout << "Couldn't find output line:" << pinName
+                 << " on GPIO. Skipping...\n";
+
+            return;
+        }
+        outputLine.request(
+            {"Disable line", ::gpiod::line_request::DIRECTION_OUTPUT, 0},
+            pinValue);
+    }
+    catch (const system_error&)
+    {
+        cerr << "Failed to set post-action GPIO" << endl;
+    }
+}
+
+bool executePreAction(const nlohmann::json& json, const string& file)
+{
+    if ((json["frus"][file].at(0)).find("presence") !=
+        json["frus"][file].at(0).end())
+    {
+        if (((json["frus"][file].at(0)["presence"]).find("pin") !=
+             json["frus"][file].at(0)["presence"].end()) &&
+            ((json["frus"][file].at(0)["presence"]).find("value") !=
+             json["frus"][file].at(0)["presence"].end()))
+        {
+            string presPinName = json["frus"][file].at(0)["presence"]["pin"];
+            Byte presPinValue = json["frus"][file].at(0)["presence"]["value"];
+
+            try
+            {
+                gpiod::line presenceLine = gpiod::find_line(presPinName);
+
+                if (!presenceLine)
+                {
+                    cerr << "couldn't find presence line:" << presPinName
+                         << "\n";
+                    executePostFailAction(json, file);
+                    return false;
+                }
+
+                presenceLine.request({"Read the presence line",
+                                      gpiod::line_request::DIRECTION_INPUT, 0});
+
+                Byte gpioData = presenceLine.get_value();
+
+                if (gpioData != presPinValue)
+                {
+                    executePostFailAction(json, file);
+                    return false;
+                }
+            }
+            catch (system_error&)
+            {
+                cerr << "Failed to get the presence GPIO for - " << presPinName
+                     << endl;
+                executePostFailAction(json, file);
+                return false;
+            }
+        }
+    }
+
+    if ((json["frus"][file].at(0)).find("preAction") !=
+        json["frus"][file].at(0).end())
+    {
+        if (((json["frus"][file].at(0)["preAction"]).find("pin") !=
+             json["frus"][file].at(0)["preAction"].end()) &&
+            ((json["frus"][file].at(0)["preAction"]).find("value") !=
+             json["frus"][file].at(0)["preAction"].end()))
+        {
+            string pinName = json["frus"][file].at(0)["preAction"]["pin"];
+            // Get the value to set
+            Byte pinValue = json["frus"][file].at(0)["preAction"]["value"];
+
+            cout << "Setting GPIO: " << pinName << " to " << (int)pinValue
+                 << endl;
+            try
+            {
+                gpiod::line outputLine = gpiod::find_line(pinName);
+
+                if (!outputLine)
+                {
+                    cout << "Couldn't find output line:" << pinName
+                         << " on GPIO. Skipping...\n";
+
+                    return false;
+                }
+                outputLine.request({"FRU pre-action",
+                                    ::gpiod::line_request::DIRECTION_OUTPUT, 0},
+                                   pinValue);
+            }
+            catch (system_error&)
+            {
+                cerr << "Failed to set pre-action for GPIO - " << pinName
+                     << endl;
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
 void insertOrMerge(inventory::InterfaceMap& map,
                    const inventory::Interface& interface,
                    inventory::PropertyMap&& property)
@@ -628,4 +763,4 @@
     }
 }
 } // namespace vpd
-} // namespace openpower
\ No newline at end of file
+} // namespace openpower