Skip to content

Commit

Permalink
FruDevice: improve warning messages in FRU parse logic
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Andrei Kartashev committed Nov 25, 2020
1 parent 272bafd commit b45324a
Showing 1 changed file with 31 additions and 14 deletions.
45 changes: 31 additions & 14 deletions src/FruDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ const static constexpr char* BASEBOARD_FRU_LOCATION =

const static constexpr char* I2C_DEV_LOCATION = "/dev";

enum class resCodes
{
resOK,
resWarn,
resErr
};

enum class fruAreas
{
fruAreaInternal = 0,
Expand Down Expand Up @@ -611,7 +618,7 @@ int getBusFRUs(int file, int first, int last, int bus,
// 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;
}
Expand Down Expand Up @@ -979,13 +986,14 @@ static void checkLang(uint8_t lang)
}
}

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()));
Expand All @@ -1008,13 +1016,13 @@ bool formatFRU(const std::vector<uint8_t>& fruBytes,
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;
Expand All @@ -1034,7 +1042,7 @@ bool formatFRU(const std::vector<uint8_t>& fruBytes,
ss << "\tThe read checksum: 0x" << std::setw(2)
<< static_cast<int>(*fruBytesIterEndArea) << "\n";
std::cerr << ss.str();
return false;
ret = resCodes::resWarn;
}

switch (area)
Expand Down Expand Up @@ -1070,7 +1078,7 @@ bool formatFRU(const std::vector<uint8_t>& fruBytes,
if (bytes == 0)
{
std::cerr << "invalid time string encountered\n";
return false;
return resCodes::resErr;
}

result["BOARD_MANUFACTURE_DATE"] = std::string(timeString);
Expand All @@ -1092,7 +1100,7 @@ bool formatFRU(const std::vector<uint8_t>& fruBytes,
{
std::cerr << "Internal error: unexpected FRU area index: "
<< static_cast<int>(area) << " \n";
return false;
return resCodes::resErr;
}
}
size_t fieldIndex = 0;
Expand Down Expand Up @@ -1130,12 +1138,13 @@ bool formatFRU(const std::vector<uint8_t>& fruBytes,
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
Expand All @@ -1145,6 +1154,7 @@ bool formatFRU(const std::vector<uint8_t>& fruBytes,
std::cerr << "Mandatory fields absent in FRU area "
<< getFruAreaName(area) << " after " << name
<< "\n";
ret = resCodes::resWarn;
}
}
} while (state == DecodeState::ok);
Expand All @@ -1155,12 +1165,13 @@ bool formatFRU(const std::vector<uint8_t>& fruBytes,
{
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)
Expand Down Expand Up @@ -1188,12 +1199,18 @@ void AddFRUObjectToDbus(
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;
Expand Down Expand Up @@ -1355,7 +1372,7 @@ bool writeFRU(uint8_t bus, uint8_t address, const std::vector<uint8_t>& fru)
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;
Expand Down

0 comments on commit b45324a

Please sign in to comment.