Additional change to support ee1004 driver

 changed the code to remove hardcoding of driver
 changed read parser executable to take driver as input

Change-Id: I6909e2d56d4572e3ff78610248683a75337bbd72
Signed-off-by: jinuthomas <jinu.joy.thomas@in.ibm.com>
diff --git a/.gitignore b/.gitignore
index 6da54be..7d18ee6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
 build*/
 subprojects/*
 !subprojects/*.wrap
+.*
diff --git a/const.hpp b/const.hpp
index db273e8..6cafd6f 100644
--- a/const.hpp
+++ b/const.hpp
@@ -110,10 +110,13 @@
 constexpr auto errIntfForGpioError = "com.ibm.VPD.Error.GPIOError";
 constexpr auto motherBoardInterface =
     "xyz.openbmc_project.Inventory.Item.Board.Motherboard";
-constexpr auto systemVpdFilePath = "/sys/bus/i2c/drivers/at24/8-0050/eeprom";
-constexpr auto i2cPathPrefix = "/sys/bus/i2c/drivers/at24/";
-constexpr auto spiPathPrefix = "/sys/bus/spi/drivers/at25/";
 constexpr auto invItemIntf = "xyz.openbmc_project.Inventory.Item";
+constexpr auto systemVpdFilePath = "/sys/bus/i2c/drivers/at24/8-0050/eeprom";
+constexpr auto i2cPathPrefix = "/sys/bus/i2c/drivers/";
+constexpr auto spiPathPrefix = "/sys/bus/spi/drivers/";
+constexpr auto at24driver = "at24";
+constexpr auto at25driver = "at25";
+constexpr auto ee1004driver = "ee1004";
 
 namespace lengths
 {
@@ -166,7 +169,7 @@
     DDR5_DDIMM_MEMORY_VPD,  /**< DDR5 DDIMM Memory VPD type */
     DDR4_ISDIMM_MEMORY_VPD, /**< DDR4 ISDIMM Memory VPD type */
     DDR5_ISDIMM_MEMORY_VPD, /**< DDR5 ISDIMM Memory VPD type */
-    INVALID_VPD_FORMAT      /**< Invalid VPD type */
+    INVALID_VPD_FORMAT      /**< Invalid VPD type Format */
 };
 
 enum PelSeverity
diff --git a/ibm_vpd_app.cpp b/ibm_vpd_app.cpp
index 94b7f55..b54af12 100644
--- a/ibm_vpd_app.cpp
+++ b/ibm_vpd_app.cpp
@@ -203,8 +203,8 @@
     }
     catch (const exception& e)
     {
-        cerr << "Failed to expand location code with exception: " << e.what()
-             << "\n";
+        std::cerr << "Failed to expand location code with exception: "
+                  << e.what() << "\n";
     }
     return expanded;
 }
@@ -262,12 +262,12 @@
                 }
                 else
                 {
-                    cerr << "Unknown Keyword[" << kw << "] found ";
+                    std::cerr << "Unknown Keyword[" << kw << "] found ";
                 }
             }
             else
             {
-                cerr << "Unknown Variant found ";
+                std::cerr << "Unknown Variant found ";
             }
         }
         else
@@ -508,17 +508,18 @@
             {
                 // Now bind the device
                 string bind = json["frus"][file].at(0).value("devAddress", "");
-                cout << "Binding device " << bind << std::endl;
+                std::cout << "Binding device " << bind << std::endl;
                 string bindCmd = string("echo \"") + bind +
                                  string("\" > /sys/bus/i2c/drivers/at24/bind");
-                cout << bindCmd << std::endl;
+                std::cout << bindCmd << std::endl;
                 executeCmd(bindCmd);
 
                 // Check if device showed up (test for file)
                 if (!fs::exists(file))
                 {
-                    cerr << "EEPROM " << file
-                         << " does not exist. Take failure action" << std::endl;
+                    std::cerr << "EEPROM " << file
+                              << " does not exist. Take failure action"
+                              << std::endl;
                     // If not, then take failure postAction
                     executePostFailAction(json, file);
                 }
@@ -526,11 +527,11 @@
             else
             {
                 // missing required informations
-                cerr << "VPD inventory JSON missing basic informations of "
-                        "preAction "
-                        "for this FRU : ["
-                     << file << "]. Executing executePostFailAction."
-                     << std::endl;
+                std::cerr << "VPD inventory JSON missing basic informations of "
+                             "preAction "
+                             "for this FRU : ["
+                          << file << "]. Executing executePostFailAction."
+                          << std::endl;
 
                 // Take failure postAction
                 executePostFailAction(json, file);
@@ -1354,6 +1355,7 @@
     json js{};
     Binary vpdVector{};
     string file{};
+    string driver{};
     // map to hold additional data in case of logging pel
     PelAdditionalData additionalData{};
 
@@ -1366,12 +1368,16 @@
 
     try
     {
-        App app{"ibm-read-vpd - App to read IPZ format VPD, parse it and store "
-                "in DBUS"};
+        App app{"ibm-read-vpd - App to read IPZ/Jedec format VPD, parse it and "
+                "store it in DBUS"};
 
         app.add_option("-f, --file", file, "File containing VPD (IPZ/KEYWORD)")
             ->required();
 
+        app.add_option("--driver", driver,
+                       "Driver used by kernel (at24,at25,ee1004)")
+            ->required();
+
         CLI11_PARSE(app, argc, argv);
 
         // PEL severity should be ERROR in case of any system VPD failure
@@ -1380,6 +1386,23 @@
             pelSeverity = PelSeverity::ERROR;
         }
 
+        // Check if input file is not empty.
+        if ((file.empty()) || (driver.empty()))
+        {
+            std::cerr << "Encountered empty input parameter file [" << file
+                      << "] driver [" << driver << "]" << std::endl;
+            return 0;
+        }
+
+        // Check if currently supported driver or not
+        if ((driver != at24driver) && (driver != at25driver) &&
+            (driver != ee1004driver))
+        {
+            std::cerr << "The driver [" << driver << "] is not supported."
+                      << std::endl;
+            return 0;
+        }
+
         auto jsonToParse = INVENTORY_JSON_DEFAULT;
 
         // If the symlink exists, it means it has been setup for us, switch the
@@ -1416,31 +1439,34 @@
         if (file.find("/ahb:apb") != string::npos)
         {
             // Translate udev path to a generic /sys/bus/.. file path.
-            udevToGenericPath(file);
+            udevToGenericPath(file, driver);
 
             if ((js["frus"].find(file) != js["frus"].end()) &&
                 (file == systemVpdFilePath))
             {
-                // We have already collected system VPD, skip.
+                std::cout << "We have already collected system VPD, skiping."
+                          << std::endl;
                 return 0;
             }
         }
 
         if (file.empty())
         {
-            cerr << "The EEPROM path <" << file << "> is not valid.";
+            std::cerr << "The EEPROM path <" << file << "> is not valid.";
             return 0;
         }
         if (js["frus"].find(file) == js["frus"].end())
         {
+            std::cerr << "The EEPROM path [" << file
+                      << "] is not found in the json." << std::endl;
             return 0;
         }
 
         if (!fs::exists(file))
         {
-            cout << "Device path: " << file
-                 << " does not exist. Spurious udev event? Exiting."
-                 << std::endl;
+            std::cout << "Device path: " << file
+                      << " does not exist. Spurious udev event? Exiting."
+                      << std::endl;
             return 0;
         }
 
@@ -1464,7 +1490,8 @@
             if ("xyz.openbmc_project.State.Chassis.PowerState.On" ==
                 getPowerState())
             {
-                cout << "This VPD cannot be read when power is ON" << std::endl;
+                std::cout << "This VPD cannot be read when power is ON"
+                          << std::endl;
                 return 0;
             }
         }
@@ -1472,7 +1499,7 @@
         // Check if this VPD should be recollected at all
         if (!needsRecollection(js, file))
         {
-            cout << "Skip VPD recollection for: " << file << std::endl;
+            std::cout << "Skip VPD recollection for: " << file << std::endl;
             return 0;
         }
 
@@ -1517,7 +1544,7 @@
         additionalData.emplace("DESCRIPTION", ex.what());
         createPEL(additionalData, pelSeverity, errIntfForJsonFailure, nullptr);
 
-        cerr << ex.what() << "\n";
+        std::cerr << ex.what() << "\n";
         rc = -1;
     }
     catch (const VpdEccException& ex)
@@ -1527,21 +1554,21 @@
                                INVENTORY_PATH + baseFruInventoryPath);
         createPEL(additionalData, pelSeverity, errIntfForEccCheckFail, nullptr);
         dumpBadVpd(file, vpdVector);
-        cerr << ex.what() << "\n";
+        std::cerr << ex.what() << "\n";
         rc = -1;
     }
     catch (const VpdDataException& ex)
     {
         if (isThisPcieOnPass1planar(js, file))
         {
-            cout << "Pcie_device  [" << file
-                 << "]'s VPD is not valid on PASS1 planar.Ignoring.\n";
+            std::cout << "Pcie_device  [" << file
+                      << "]'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";
+            std::cout << "FRU at: " << file
+                      << " is not detected present. Ignore parser error.\n";
             rc = 0;
         }
         else
@@ -1563,7 +1590,7 @@
     catch (const exception& e)
     {
         dumpBadVpd(file, vpdVector);
-        cerr << e.what() << "\n";
+        std::cerr << e.what() << "\n";
         rc = -1;
     }
 
diff --git a/ibm_vpd_utils.cpp b/ibm_vpd_utils.cpp
index 388d869..8d93606 100644
--- a/ibm_vpd_utils.cpp
+++ b/ibm_vpd_utils.cpp
@@ -533,7 +533,7 @@
     return jsonPath;
 }
 
-void udevToGenericPath(std::string& file)
+void udevToGenericPath(std::string& file, const std::string& driver)
 {
     // Sample udevEvent i2c path :
     // "/sys/devices/platform/ahb/ahb:apb/ahb:apb:bus@1e78a000/1e78a480.i2c-bus/i2c-8/8-0051/8-00510/nvmem"
@@ -560,7 +560,7 @@
             exit(EXIT_SUCCESS);
         }
         // Forming the generic file path
-        file = i2cPathPrefix + i2cBusAddr + "/eeprom";
+        file = i2cPathPrefix + driver + "/" + i2cBusAddr + "/eeprom";
     }
     // Sample udevEvent spi path :
     // "/sys/devices/platform/ahb/ahb:apb/1e79b000.fsi/fsi-master/fsi0/slave@00:00/00:00:00:04/spi_master/spi2/spi2.0/spi2.00/nvmem"
@@ -588,7 +588,7 @@
             exit(EXIT_SUCCESS);
         }
         // Forming the generic path
-        file = spiPathPrefix + spiBus + ".0/eeprom";
+        file = spiPathPrefix + driver + "/" + spiBus + ".0/eeprom";
     }
     else
     {
diff --git a/ibm_vpd_utils.hpp b/ibm_vpd_utils.hpp
index 8a64d16..18ee819 100644
--- a/ibm_vpd_utils.hpp
+++ b/ibm_vpd_utils.hpp
@@ -293,8 +293,9 @@
 
 /** @brief Translate udev event generated path to a generic /sys/bus eeprom path
  *  @param[io] file - path generated from udev event.
+ *  @param[in] driver - kernel driver used by the device.
  */
-void udevToGenericPath(std::string& file);
+void udevToGenericPath(std::string& file, const std::string& driver);
 
 /**
  * @brief API to generate a vpd name in some pattern.