summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDeepak Kodihalli <dkodihal@in.ibm.com>2016-11-24 07:08:20 -0600
committerDeepak Kodihalli <dkodihal@in.ibm.com>2016-12-08 12:37:26 -0600
commit4a475bda35c8c6c985f81f1dbecdba9a55d46782 (patch)
tree1b70d7a0e6963f45d77177f4879517f08938d2fd
parenta1143460569a61869892e87f9b7a89682c596b46 (diff)
downloadopenpower-vpd-parser-4a475bda35c8c6c985f81f1dbecdba9a55d46782.tar.gz
openpower-vpd-parser-4a475bda35c8c6c985f81f1dbecdba9a55d46782.zip
parser : parse keyword data section
For keywords contained in an OpenPOWER VPD record, read the keyword data. The data may be raw or encoded in ascii. Return the resultant data as a string. Some keywords, such as B1 (MAC address) need to be decoded specially. Change-Id: I64c16c60dc94e173586b20fb6a92809fbb0ac89e Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
-rw-r--r--impl.cpp81
-rw-r--r--impl.hpp26
2 files changed, 107 insertions, 0 deletions
diff --git a/impl.cpp b/impl.cpp
index 834cc6c..de1896f 100644
--- a/impl.cpp
+++ b/impl.cpp
@@ -1,6 +1,11 @@
+#include <sstream>
#include <exception>
#include <iostream>
#include <iterator>
+#include <iomanip>
+#include <tuple>
+#include <algorithm>
+#include "defines.hpp"
#include "impl.hpp"
namespace openpower
@@ -17,6 +22,22 @@ static const std::unordered_map<std::string, Record> supportedRecords =
{"OSYS", Record::OSYS}
};
+static constexpr auto MAC_ADDRESS_LEN_BYTES = 6;
+
+static const std::unordered_map<std::string,
+ internal::KeywordInfo> supportedKeywords =
+{
+ {"DR", std::make_tuple(record::Keyword::DR, keyword::Encoding::ASCII)},
+ {"PN", std::make_tuple(record::Keyword::PN, keyword::Encoding::ASCII)},
+ {"SN", std::make_tuple(record::Keyword::SN, keyword::Encoding::ASCII)},
+ {"CC", std::make_tuple(record::Keyword::CC, keyword::Encoding::ASCII)},
+ {"HW", std::make_tuple(record::Keyword::HW, keyword::Encoding::RAW)},
+ {"B1", std::make_tuple(record::Keyword::B1, keyword::Encoding::B1)},
+ {"VN", std::make_tuple(record::Keyword::VN, keyword::Encoding::ASCII)},
+ {"MB", std::make_tuple(record::Keyword::MB, keyword::Encoding::RAW)},
+ {"MM", std::make_tuple(record::Keyword::MM, keyword::Encoding::ASCII)}
+};
+
namespace
{
@@ -29,6 +50,12 @@ using KwSize = uint8_t;
using ECCOffset = uint16_t;
using ECCLength = uint16_t;
+constexpr auto toHex(size_t c)
+{
+ constexpr auto map = "0123456789abcdef";
+ return map[c];
+}
+
}
namespace offsets
@@ -175,6 +202,60 @@ void Impl::processRecord(std::size_t recordOffset)
}
}
+std::string Impl::readKwData(const internal::KeywordInfo& keyword,
+ std::size_t dataLength,
+ Binary::const_iterator iterator)
+{
+ switch (std::get<keyword::Encoding>(keyword))
+ {
+ case keyword::Encoding::ASCII:
+ {
+ auto stop = std::next(iterator, dataLength);
+ return std::string(iterator, stop);
+ }
+
+ case keyword::Encoding::RAW:
+ {
+ auto stop = std::next(iterator, dataLength);
+ std::string data(iterator, stop);
+ std::string result {};
+ std::for_each(data.cbegin(), data.cend(),
+ [&result](size_t c)
+ {
+ result += toHex(c >> 4);
+ result += toHex(c & 0x0F);
+ });
+ return result;
+ }
+
+ case keyword::Encoding::B1:
+ {
+ //B1 is MAC address, represent as AA:BB:CC:DD:EE:FF
+ auto stop = std::next(iterator, MAC_ADDRESS_LEN_BYTES);
+ std::string data(iterator, stop);
+ std::string result {};
+ auto strItr = data.cbegin();
+ size_t firstDigit = *strItr;
+ result += toHex(firstDigit >> 4);
+ result += toHex(firstDigit & 0x0F);
+ std::advance(strItr, 1);
+ std::for_each(strItr, data.cend(),
+ [&result](size_t c)
+ {
+ result += ":";
+ result += toHex(c >> 4);
+ result += toHex(c & 0x0F);
+ });
+ return result;
+ }
+
+ default:
+ break;
+ }
+
+ return {};
+}
+
} // namespace parser
} // namespace vpd
} // namespace openpower
diff --git a/impl.hpp b/impl.hpp
index 846d34a..42a5c44 100644
--- a/impl.hpp
+++ b/impl.hpp
@@ -9,10 +9,24 @@ namespace vpd
{
namespace parser
{
+namespace keyword
+{
+
+/** @brief Encoding scheme of a VPD keyword's data */
+enum class Encoding
+{
+ ASCII, /**< data encoded in ascii */
+ RAW, /**< raw data */
+ // Keywords needing custom decoding
+ B1 /**< The keyword B1 needs to be decoded specially */
+};
+
+} // namespace keyword
namespace internal
{
+using KeywordInfo = std::tuple<record::Keyword, keyword::Encoding>;
using OffsetList = std::vector<uint32_t>;
}
@@ -86,6 +100,18 @@ class Impl
*/
void processRecord(std::size_t recordOffset);
+ /** @brief Read keyword data
+ *
+ * @param[in] keyword - OpenPOWER VPD keyword
+ * @param[in] dataLength - Length of data to be read
+ * @param[in] iterator - iterator pointing to a Keyword's data in
+ * the VPD
+ *
+ * @returns keyword data as a string
+ */
+ std::string readKwData(const internal::KeywordInfo& keyword,
+ std::size_t dataLength,
+ Binary::const_iterator iterator);
/** @brief Checks if the VHDR record is present in the VPD */
void checkHeader() const;
OpenPOWER on IntegriCloud