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_app.cpp b/ibm_vpd_app.cpp
index ae4d1be..edc95c9 100644
--- a/ibm_vpd_app.cpp
+++ b/ibm_vpd_app.cpp
@@ -430,168 +430,42 @@
     return vpdVector;
 }
 
-/** This API will be called at the end of VPD collection to perform any post
- * actions.
- *
- * @param[in] json - json object
- * @param[in] file - eeprom file path
- */
-static void postFailAction(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;
-    }
-}
-
-/**
- * @brief This sets the appropriate value to presence GPIO based on device
- * attached or not on expander GPIO, which enables that FRU's VPD collection.
+/** Performs any pre-action needed to get the FRU setup for collection.
  *
  * @param[in] json - json object
  * @param[in] file - eeprom file path
  */
 static void preAction(const nlohmann::json& json, const string& file)
 {
-    if ((json["frus"][file].at(0)).find("presence") !=
+    if ((json["frus"][file].at(0)).find("preAction") ==
         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";
-                    return;
-                }
-
-                presenceLine.request({"Read the presence line",
-                                      gpiod::line_request::DIRECTION_INPUT, 0});
-
-                Byte gpioData = presenceLine.get_value();
-
-                if (gpioData != presPinValue)
-                {
-                    return;
-                }
-            }
-            catch (system_error&)
-            {
-                cerr << "Failed to get the presence GPIO for - " << presPinName
-                     << endl;
-                return;
-            }
-        }
+        return;
     }
 
-    if ((json["frus"][file].at(0)).find("preAction") !=
-        json["frus"][file].at(0).end())
+    if (executePreAction(json, file))
     {
-        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()))
+        if (json["frus"][file].at(0).find("devAddress") !=
+            json["frus"][file].at(0).end())
         {
-            string pinName = json["frus"][file].at(0)["preAction"]["pin"];
-            // Get the value to set
-            Byte pinValue = json["frus"][file].at(0)["preAction"]["value"];
+            // Now bind the device
+            string bind = json["frus"][file].at(0).value("devAddress", "");
+            cout << "Binding device " << bind << endl;
+            string bindCmd = string("echo \"") + bind +
+                             string("\" > /sys/bus/i2c/drivers/at24/bind");
+            cout << bindCmd << endl;
+            executeCmd(bindCmd);
+        }
 
-            cout << "Setting GPIO: " << pinName << " to " << (int)pinValue
+        // Check if device showed up (test for file)
+        if (!fs::exists(file))
+        {
+            cout << "EEPROM " << file << " does not exist. Take failure action"
                  << 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({"FRU pre-action",
-                                    ::gpiod::line_request::DIRECTION_OUTPUT, 0},
-                                   pinValue);
-            }
-            catch (system_error&)
-            {
-                cerr << "Failed to set pre-action for GPIO - " << pinName
-                     << endl;
-                return;
-            }
+            // If not, then take failure postAction
+            executePostFailAction(json, file);
         }
     }
-
-    // Now bind the device
-    if (json["frus"][file].at(0).find("devAddress") !=
-        json["frus"][file].at(0).end())
-    {
-        string bind = json["frus"][file].at(0).value("devAddress", "");
-        cout << "Binding device " << bind << endl;
-        string bindCmd = string("echo \"") + bind +
-                         string("\" > /sys/bus/i2c/drivers/at24/bind");
-        cout << bindCmd << endl;
-        executeCmd(bindCmd);
-    }
-
-    // Check if device showed up (test for file)
-    if (!fs::exists(file))
-    {
-        cout << "EEPROM " << file << " does not exist. Take failure action"
-             << endl;
-        // If not, then take failure postAction
-        postFailAction(json, file);
-    }
 }
 
 /**
@@ -1501,7 +1375,7 @@
         }
         catch (const exception& e)
         {
-            postFailAction(js, file);
+            executePostFailAction(js, file);
             throw;
         }
     }
@@ -1555,4 +1429,4 @@
     }
 
     return rc;
-}
+}
\ No newline at end of file
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
diff --git a/ibm_vpd_utils.hpp b/ibm_vpd_utils.hpp
index 11db6f7..1432241 100644
--- a/ibm_vpd_utils.hpp
+++ b/ibm_vpd_utils.hpp
@@ -5,6 +5,7 @@
 #include "types.hpp"
 
 #include <iostream>
+#include <nlohmann/json.hpp>
 
 using namespace std;
 
@@ -261,6 +262,24 @@
 string byteArrayToHexString(const Binary& vec);
 
 /**
+ * @brief Performs any pre-action needed to get the FRU setup for collection.
+ *
+ * @param[in] json - json object
+ * @param[in] file - eeprom file path
+ * @return - success or failure
+ */
+bool executePreAction(const nlohmann::json& json, const string& file);
+
+/**
+ * @brief This API will be called at the end of VPD collection to perform any
+ * post actions.
+ *
+ * @param[in] json - json object
+ * @param[in] file - eeprom file path
+ */
+void executePostFailAction(const nlohmann::json& json, const string& file);
+
+/**
  * @brief Helper function to insert or merge in map.
  *
  * This method checks in the given inventory::InterfaceMap if the given
@@ -279,4 +298,4 @@
                    inventory::PropertyMap&& property);
 
 } // namespace vpd
-} // namespace openpower
\ No newline at end of file
+} // namespace openpower
diff --git a/meson.build b/meson.build
index a102a3f..f1bc49f 100644
--- a/meson.build
+++ b/meson.build
@@ -132,7 +132,8 @@
                                  'vpd-tool',
                                  vpd_tool_SOURCES,
                                  dependencies: [
-                                   sdbusplus
+                                   sdbusplus,
+                                   libgpiodcxx
                                    ],
                                  install: true,
                                  include_directories : vpd_tool_INCLUDE
diff --git a/test/meson.build b/test/meson.build
index 4aaaeea..36d5383 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -11,7 +11,8 @@
 else
   dynamic_linker = []
 endif
-dependecy_list = [gtest_dep, gmock_dep, sdbusplus, phosphor_logging, phosphor_dbus_interfaces]
+libgpiodcxx = dependency('libgpiodcxx')
+dependecy_list = [gtest_dep, gmock_dep, sdbusplus, phosphor_logging, phosphor_dbus_interfaces, libgpiodcxx]
 
 configuration_inc = include_directories('..', '../vpd-manager', 'vpd-manager-test', '../vpd-parser')