vpd-tool: Flow to read keyword from hardware updated

The commit implements change to check if the offset passed by the user
for a given EEPROM path is equal to the offset if defined for that
EEPROM in inventory JSON.
In case of any mismatch, error message is flagged to the user.

As all EEPROMs are not modelled in inventory JSON file, In order to
handle case where an EEPROM path passed by user is not present in JSON,
check has been added to avoid any exception thrown due to extraction of
inventory path from JSON based on the passed EEPROM path.

Test cases:

CASE1: Trying to read from i2c FRU

/tmp/vpd-tool -r -H -O "/sys/bus/i2c/drivers/at24/8-0050/eeprom" -R VINI -K PN --seek 0x30000
Invalid offset, please correct the offset
Recommended Offset is: 0

/tmp/vpd-tool -r -H -O "/sys/bus/i2c/drivers/at24/8-0050/eeprom" -R VINI -K PN
{
    "/sys/bus/i2c/drivers/at24/8-0050/eeprom": {
        "PN": "00L5521"
    }
}

CASE2: Trying to read from proc and EEPROM not defined in JSON:

/tmp/vpd-tool -r -H -O /sys/bus/spi/drivers/at25/spi22.0/eeprom  -R VINI -K CC
Invalid offset, please correct the offset
Recommended Offset is: 196608

/tmp/vpd-tool -r -H -O /sys/bus/spi/drivers/at25/spi22.0/eeprom  -R VINI -K CC --seek 0x30000
{
    "/sys/bus/spi/drivers/at25/spi22.0/eeprom": {
        "CC": "5C5F"
    }
}
/tmp/vpd-tool -r -H -O /sys/bus/spi/drivers/at25/spi23.0/eeprom  -R VINI -K CC --seek 0x30000
{
    "/sys/bus/spi/drivers/at25/spi23.0/eeprom": {
        "CC": "5C5F"
    }
}

/tmp/vpd-tool -r -H -O /sys/bus/spi/drivers/at25/spi23.0/eeprom  -R VINI -K CC --seek 0x3000
VHDR record not found
Did you provide a valid offset? By default VPD offset is taken as 0. To input offset, use --seek. Refer vpd-tool help.

/tmp/vpd-tool -r -H -O /sys/bus/spi/drivers/at25/spi23.0/eeprom  -R VINI -K CC
VHDR record not found
Did you provide a valid offset? By default VPD offset is taken as 0. To input offset, use --seek. Refer vpd-tool help.

/tmp/vpd-tool -r -H -O /sys/bus/spi/drivers/at25/spi22.0/eeprom  -R VINI -K CC --seek 0x3000
Invalid offset, please correct the offset
Recommended Offset is: 196608

Signed-off-by: Giridhari Krishna <giridharikrishnan@gmail.com>
Change-Id: I246ca983fc75490999f18386bf60e949959d49d2
diff --git a/vpd_tool.cpp b/vpd_tool.cpp
index 0f27f52..ca48a39 100644
--- a/vpd_tool.cpp
+++ b/vpd_tool.cpp
@@ -233,9 +233,10 @@
 
         if (*Hardware)
         {
-            std::cerr << "Did you provide a valid offset? By default VPD "
-                         "offset is taken as 0. To input offset, use --seek. "
-                         "Refer vpd-tool help."
+            std::cerr << std::endl
+                      << "Did you provide a valid offset? By"
+                         " default VPD offset is taken as 0. To input offset,"
+                         " use --seek. Refer vpd-tool help."
                       << std::endl;
         }
         rc = -1;
diff --git a/vpd_tool_impl.cpp b/vpd_tool_impl.cpp
index d46637f..ff0dfad 100644
--- a/vpd_tool_impl.cpp
+++ b/vpd_tool_impl.cpp
@@ -659,6 +659,30 @@
     Binary completeVPDFile;
     completeVPDFile.resize(65504);
     fstream vpdFileStream;
+    std::string inventoryPath;
+
+    if (jsonFile["frus"].contains(fruPath))
+    {
+        uint32_t vpdStartOffset = 0;
+
+        for (const auto& item : jsonFile["frus"][fruPath])
+        {
+            if (item.find("offset") != item.end())
+            {
+                vpdStartOffset = item["offset"];
+                break;
+            }
+        }
+
+        if ((startOffset != vpdStartOffset))
+        {
+            std::cerr << "Invalid offset, please correct the offset" << endl;
+            std::cerr << "Recommended Offset is: " << vpdStartOffset << endl;
+            return;
+        }
+        inventoryPath = jsonFile["frus"][fruPath][0]["inventoryPath"];
+    }
+
     vpdFileStream.open(fruPath,
                        std::ios::in | std::ios::out | std::ios::binary);
 
@@ -672,20 +696,8 @@
         throw std::runtime_error("Invalid File");
     }
 
-    const std::string& inventoryPath =
-        jsonFile["frus"][fruPath][0]["inventoryPath"];
-
-    uint32_t vpdStartOffset = 0;
-    for (const auto& item : jsonFile["frus"][fruPath])
-    {
-        if (item.find("offset") != item.end())
-        {
-            vpdStartOffset = item["offset"];
-        }
-    }
-
     Impl obj(completeVPDFile, (constants::pimPath + inventoryPath), fruPath,
-             vpdStartOffset);
+             startOffset);
     std::string keywordVal = obj.readKwFromHw(recordName, keyword);
 
     keywordVal = getPrintableValue(keywordVal);