diff options
author | Deepak Kodihalli <dkodihal@in.ibm.com> | 2016-11-24 07:08:20 -0600 |
---|---|---|
committer | Deepak Kodihalli <dkodihal@in.ibm.com> | 2016-12-08 12:37:26 -0600 |
commit | 4a475bda35c8c6c985f81f1dbecdba9a55d46782 (patch) | |
tree | 1b70d7a0e6963f45d77177f4879517f08938d2fd | |
parent | a1143460569a61869892e87f9b7a89682c596b46 (diff) | |
download | openpower-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.cpp | 81 | ||||
-rw-r--r-- | impl.hpp | 26 |
2 files changed, 107 insertions, 0 deletions
@@ -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 @@ -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; |