FruDevice: improve warning messages in FRU parse logic

When got any warnings while formatFRU, is hard to understand which
device cause it since formatFRU has no information about device address.
This adds printing device address after parsing FRU data if
error/warning occurs.

Makes some check to be not critical (checksum error and non-zero bytes
after EndOfFields) since we found invalid FRU in FLEXTRONICS
S-1100ADU00-201 PSU where was wrong size in PRODUCT section header:

00000000  01 00 00 00 01 09 00 f5  01 09 19 cb 46 4c 45 58  |............FLEX|
00000010  54 52 4f 4e 49 43 53 cf  53 2d 31 31 30 30 41 44  |TRONICS.S-1100AD|
00000020  55 30 30 2d 32 30 31 ca  47 38 34 30 32 37 2d 30  |U00-201.G84027-0|
00000030  30 37 c2 30 31 cc 45 58  57 44 36 34 39 30 31 31  |07.01.EXWD649011|
00000040  32 31 c0 c0 c1 00 00 dc  00 02 18 3f a7 4c 04 28  |21.........?.L.(|
00000050  0a 37 05 28 23 b0 36 50  46 20 67 2f 3f 0a 1f f8  |.7.(#.6PF g/?...|
00000060  05 00 00 00 21 01 02 0d  6d 83 01 b0 04 74 04 ec  |....!...m....t..|
00000070  04 78 00 00 00 ff ff 01  82 0d ae c2 82 b0 04 74  |.x.............t|
00000080  04 ec 04 78 00 00 00 34  08                       |...x...4.|

Also fixes some other messages.

Tested: ensure there are expected messages in the log for FRU above:
	fru-device[355]: Checksum error in FRU area PRODUCT
	fru-device[355]:         Computed checksum: 0xb0
	fru-device[355]:         The read checksum: 0x28
	fru-device[355]: Non-zero byte after EndOfFields in FRU area PRODUCT
	fru-device[355]: there were warnings while parsing FRU for device at bus 7 address 82

Change-Id: I1e1d08ca0547ec4e6a8ce4e1f71a479622d5f243
Signed-off-by: Andrei Kartashev <a.kartashev@yadro.com>
diff --git a/src/FruDevice.cpp b/src/FruDevice.cpp
index 45d0fd9..3e7cd1a 100644
--- a/src/FruDevice.cpp
+++ b/src/FruDevice.cpp
@@ -70,6 +70,13 @@
 
 const static constexpr char* I2C_DEV_LOCATION = "/dev";
 
+enum class resCodes
+{
+    resOK,
+    resWarn,
+    resErr
+};
+
 enum class fruAreas
 {
     fruAreaInternal = 0,
@@ -611,7 +618,7 @@
             // Set slave address
             if (ioctl(file, I2C_SLAVE, ii) < 0)
             {
-                std::cerr << "device at bus " << bus << " register " << ii
+                std::cerr << "device at bus " << bus << " address " << ii
                           << " busy\n";
                 continue;
             }
@@ -979,13 +986,14 @@
     }
 }
 
-bool formatFRU(const std::vector<uint8_t>& fruBytes,
-               boost::container::flat_map<std::string, std::string>& result)
+resCodes formatFRU(const std::vector<uint8_t>& fruBytes,
+                   boost::container::flat_map<std::string, std::string>& result)
 {
+    resCodes ret = resCodes::resOK;
     if (fruBytes.size() <= fruBlockSize)
     {
         std::cerr << "Error: trying to parse empty FRU \n";
-        return false;
+        return resCodes::resErr;
     }
     result["Common_Format_Version"] =
         std::to_string(static_cast<int>(*fruBytes.begin()));
@@ -1008,13 +1016,13 @@
         if (fruBytesIter + fruBlockSize >= fruBytes.end())
         {
             std::cerr << "Not enough data to parse \n";
-            return false;
+            return resCodes::resErr;
         }
         // check for format version 1
         if (*fruBytesIter != 0x01)
         {
             std::cerr << "Unexpected version " << *fruBytesIter << "\n";
-            return false;
+            return resCodes::resErr;
         }
         ++fruBytesIter;
         uint8_t fruAreaSize = *fruBytesIter * fruBlockSize;
@@ -1034,7 +1042,7 @@
             ss << "\tThe read checksum: 0x" << std::setw(2)
                << static_cast<int>(*fruBytesIterEndArea) << "\n";
             std::cerr << ss.str();
-            return false;
+            ret = resCodes::resWarn;
         }
 
         switch (area)
@@ -1070,7 +1078,7 @@
                 if (bytes == 0)
                 {
                     std::cerr << "invalid time string encountered\n";
-                    return false;
+                    return resCodes::resErr;
                 }
 
                 result["BOARD_MANUFACTURE_DATE"] = std::string(timeString);
@@ -1092,7 +1100,7 @@
             {
                 std::cerr << "Internal error: unexpected FRU area index: "
                           << static_cast<int>(area) << " \n";
-                return false;
+                return resCodes::resErr;
             }
         }
         size_t fieldIndex = 0;
@@ -1130,12 +1138,13 @@
             else if (state == DecodeState::err)
             {
                 std::cerr << "Error while parsing " << name << "\n";
+                ret = resCodes::resWarn;
                 // Cancel decoding if failed to parse any of mandatory
                 // fields
                 if (fieldIndex < fruAreaFieldNames->size())
                 {
                     std::cerr << "Failed to parse mandatory field \n";
-                    return false;
+                    return resCodes::resErr;
                 }
             }
             else
@@ -1145,6 +1154,7 @@
                     std::cerr << "Mandatory fields absent in FRU area "
                               << getFruAreaName(area) << " after " << name
                               << "\n";
+                    ret = resCodes::resWarn;
                 }
             }
         } while (state == DecodeState::ok);
@@ -1155,12 +1165,13 @@
             {
                 std::cerr << "Non-zero byte after EndOfFields in FRU area "
                           << getFruAreaName(area) << "\n";
+                ret = resCodes::resWarn;
                 break;
             }
         }
     }
 
-    return true;
+    return ret;
 }
 
 std::vector<uint8_t>& getFRUInfo(const uint8_t& bus, const uint8_t& address)
@@ -1188,12 +1199,18 @@
     uint32_t bus, uint32_t address)
 {
     boost::container::flat_map<std::string, std::string> formattedFRU;
-    if (!formatFRU(device, formattedFRU))
+    resCodes res = formatFRU(device, formattedFRU);
+    if (res == resCodes::resErr)
     {
-        std::cerr << "failed to format fru for device at bus " << bus
+        std::cerr << "failed to parse FRU for device at bus " << bus
                   << " address " << address << "\n";
         return;
     }
+    else if (res == resCodes::resWarn)
+    {
+        std::cerr << "there were warnings while parsing FRU for device at bus "
+                  << bus << " address " << address << "\n";
+    }
 
     auto productNameFind = formattedFRU.find("BOARD_PRODUCT_NAME");
     std::string productName;
@@ -1355,7 +1372,7 @@
         return false;
     }
     // verify legal fru by running it through fru parsing logic
-    if (!formatFRU(fru, tmp))
+    if (formatFRU(fru, tmp) != resCodes::resOK)
     {
         std::cerr << "Invalid fru format during writeFRU\n";
         return false;