PEL: Check Presence Before Error Logging

In case of VPD parsing exceptions, check if the FRU presence is false.
If it is, then ignore any parser errors.

This helps with cases where a card with a VPD we don't recognize
shows up at the same address, but witout the presence detect.

Signed-off-by: Santosh Puranik <santosh.puranik@in.ibm.com>
Change-Id: Ia57dec455f37db52c480b9dbbb23b3cea2ec0f14
diff --git a/ibm_vpd_app.cpp b/ibm_vpd_app.cpp
index e435cc3..613f4af 100644
--- a/ibm_vpd_app.cpp
+++ b/ibm_vpd_app.cpp
@@ -1471,6 +1471,12 @@
                  << "]'s VPD is not valid on PASS1 planar.Ignoring.\n";
             rc = 0;
         }
+        else if (!(isPresent(js, file).value_or(true)))
+        {
+            cout << "FRU at: " << file
+                 << " is not detected present. Ignore parser error.\n";
+            rc = 0;
+        }
         else
         {
             string errorMsg =
diff --git a/ibm_vpd_utils.cpp b/ibm_vpd_utils.cpp
index 2690c26..c75c0de 100644
--- a/ibm_vpd_utils.cpp
+++ b/ibm_vpd_utils.cpp
@@ -662,7 +662,8 @@
     }
 }
 
-bool executePreAction(const nlohmann::json& json, const string& file)
+std::optional<bool> isPresent(const nlohmann::json& json, const string& file)
+
 {
     if ((json["frus"][file].at(0)).find("presence") !=
         json["frus"][file].at(0).end())
@@ -683,7 +684,6 @@
                 {
                     cerr << "couldn't find presence line:" << presPinName
                          << "\n";
-                    executePostFailAction(json, file);
                     return false;
                 }
 
@@ -692,21 +692,27 @@
 
                 Byte gpioData = presenceLine.get_value();
 
-                if (gpioData != presPinValue)
-                {
-                    executePostFailAction(json, file);
-                    return false;
-                }
+                return (gpioData == presPinValue);
             }
             catch (system_error&)
             {
                 cerr << "Failed to get the presence GPIO for - " << presPinName
                      << endl;
-                executePostFailAction(json, file);
                 return false;
             }
         }
     }
+    return std::optional<bool>{};
+}
+
+bool executePreAction(const nlohmann::json& json, const string& file)
+{
+    auto present = isPresent(json, file);
+    if (present && !present.value())
+    {
+        executePostFailAction(json, file);
+        return false;
+    }
 
     if ((json["frus"][file].at(0)).find("preAction") !=
         json["frus"][file].at(0).end())
diff --git a/ibm_vpd_utils.hpp b/ibm_vpd_utils.hpp
index 1432241..47bab17 100644
--- a/ibm_vpd_utils.hpp
+++ b/ibm_vpd_utils.hpp
@@ -6,6 +6,7 @@
 
 #include <iostream>
 #include <nlohmann/json.hpp>
+#include <optional>
 
 using namespace std;
 
@@ -262,7 +263,24 @@
 string byteArrayToHexString(const Binary& vec);
 
 /**
- * @brief Performs any pre-action needed to get the FRU setup for collection.
+ * @brief Return presence of the FRU.
+ *
+ * This API returns the presence information of the FRU corresponding to the
+ * given EEPROM. If the JSON contains no information about presence detect, this
+ * will return an empty optional. Else it will get the presence GPIO information
+ * from the JSON and return the appropriate present status.
+ * In case of GPIO find/read errors, it will return false.
+ *
+ * @param[in] json - The VPD JSON
+ * @param[in] file - EEPROM file path
+ * @return Empty optional if there is no presence info. Else returns presence
+ * based on the GPIO read.
+ */
+std::optional<bool> isPresent(const nlohmann::json& json, const string& file);
+
+/**
+ * @brief Performs any pre-action needed to get the FRU setup for
+ * collection.
  *
  * @param[in] json - json object
  * @param[in] file - eeprom file path