Correction of VPD using ECC
ECC algorithm corrects VPD data in 32:1 bit ratio in the
event of corruption.
Main Test Cases:
1) Check correction of KW in records.
2) Check correction while writing and reading VPD.
3) Check for Module VPD correction.
Signed-off-by: Giridhari Krishna <giridharikrishnan@gmail.com>
Change-Id: I48a3db18df9d3a2aecde814610ab1b357e6f310d
diff --git a/impl.cpp b/impl.cpp
index a8bd694..7d51433 100644
--- a/impl.cpp
+++ b/impl.cpp
@@ -74,7 +74,7 @@
}
#ifdef IPZ_PARSER
-int Impl::vhdrEccCheck() const
+int Impl::vhdrEccCheck()
{
int rc = eccStatus::SUCCESS;
auto vpdPtr = vpd.cbegin();
@@ -84,8 +84,32 @@
lengths::VHDR_RECORD_LENGTH,
const_cast<uint8_t*>(&vpdPtr[offsets::VHDR_ECC]),
lengths::VHDR_ECC_LENGTH);
-
- if (l_status != VPD_ECC_OK)
+ if (l_status == VPD_ECC_CORRECTABLE_DATA)
+ {
+ try
+ {
+ if (vpdFileStream.is_open())
+ {
+ vpdFileStream.seekp(vpdStartOffset + offsets::VHDR_RECORD,
+ std::ios::beg);
+ vpdFileStream.write(
+ reinterpret_cast<const char*>(&vpd[offsets::VHDR_RECORD]),
+ lengths::VHDR_RECORD_LENGTH);
+ }
+ else
+ {
+ std::cerr << "File not open";
+ rc = eccStatus::FAILED;
+ }
+ }
+ catch (const std::fstream::failure& e)
+ {
+ std::cout << "Error while operating on file with exception:"
+ << e.what();
+ rc = eccStatus::FAILED;
+ }
+ }
+ else if (l_status != VPD_ECC_OK)
{
rc = eccStatus::FAILED;
}
@@ -93,7 +117,7 @@
return rc;
}
-int Impl::vtocEccCheck() const
+int Impl::vtocEccCheck()
{
int rc = eccStatus::SUCCESS;
// Use another pointer to get ECC information from VHDR,
@@ -122,8 +146,31 @@
auto l_status = vpdecc_check_data(
const_cast<uint8_t*>(&vpdPtr[vtocOffset]), vtocLength,
const_cast<uint8_t*>(&vpdPtr[vtocECCOffset]), vtocECCLength);
-
- if (l_status != VPD_ECC_OK)
+ if (l_status == VPD_ECC_CORRECTABLE_DATA)
+ {
+ try
+ {
+ if (vpdFileStream.is_open())
+ {
+ vpdFileStream.seekp(vpdStartOffset + vtocOffset, std::ios::beg);
+ vpdFileStream.write(
+ reinterpret_cast<const char*>(&vpdPtr[vtocOffset]),
+ vtocLength);
+ }
+ else
+ {
+ std::cerr << "File not open";
+ rc = eccStatus::FAILED;
+ }
+ }
+ catch (const std::fstream::failure& e)
+ {
+ std::cout << "Error while operating on file with exception "
+ << e.what();
+ rc = eccStatus::FAILED;
+ }
+ }
+ else if (l_status != VPD_ECC_OK)
{
rc = eccStatus::FAILED;
}
@@ -131,7 +178,7 @@
return rc;
}
-int Impl::recordEccCheck(Binary::const_iterator iterator) const
+int Impl::recordEccCheck(Binary::const_iterator iterator)
{
int rc = eccStatus::SUCCESS;
@@ -163,7 +210,32 @@
auto l_status = vpdecc_check_data(
const_cast<uint8_t*>(&vpdPtr[recordOffset]), recordLength,
const_cast<uint8_t*>(&vpdPtr[eccOffset]), eccLength);
- if (l_status != VPD_ECC_OK)
+ if (l_status == VPD_ECC_CORRECTABLE_DATA)
+ {
+ try
+ {
+ if (vpdFileStream.is_open())
+ {
+ vpdFileStream.seekp(vpdStartOffset + recordOffset,
+ std::ios::beg);
+ vpdFileStream.write(
+ reinterpret_cast<const char*>(&vpdPtr[recordOffset]),
+ recordLength);
+ }
+ else
+ {
+ std::cerr << "File not open";
+ rc = eccStatus::FAILED;
+ }
+ }
+ catch (const std::fstream::failure& e)
+ {
+ std::cout << "Error while operating on file with exception "
+ << e.what();
+ rc = eccStatus::FAILED;
+ }
+ }
+ else if (l_status != VPD_ECC_OK)
{
rc = eccStatus::FAILED;
}
@@ -172,7 +244,7 @@
}
#endif
-void Impl::checkHeader() const
+void Impl::checkHeader()
{
if (vpd.empty() || (lengths::RECORD_MIN > vpd.size()))
{
@@ -201,7 +273,7 @@
}
}
-std::size_t Impl::readTOC(Binary::const_iterator& iterator) const
+std::size_t Impl::readTOC(Binary::const_iterator& iterator)
{
// The offset to VTOC could be 1 or 2 bytes long
RecordOffset vtocOffset = getVtocOffset();
@@ -244,7 +316,7 @@
}
internal::OffsetList Impl::readPT(Binary::const_iterator iterator,
- std::size_t ptLength) const
+ std::size_t ptLength)
{
internal::OffsetList offsets{};