diff options
author | Matt Spinler <spinler@us.ibm.com> | 2019-09-25 13:11:22 -0500 |
---|---|---|
committer | Matt Spinler <spinler@us.ibm.com> | 2019-10-09 13:12:29 +0000 |
commit | 14d671fa2311144fe43047486c4938e9c461ce24 (patch) | |
tree | 8298db4f6ef9c1a051b739df1ea79e032170f811 | |
parent | d377793c6fe0b8ea8755d2526c1ef20d51f5043e (diff) | |
download | phosphor-logging-14d671fa2311144fe43047486c4938e9c461ce24.tar.gz phosphor-logging-14d671fa2311144fe43047486c4938e9c461ce24.zip |
PEL: Add a Generic section object
This object will be created when unflattening a PEL when there is no
other class to use for that section. It just contains a vector<uint8_t>
for its data.
This is done so that the code can always have objects for all PEL
sections, which helps in validating (can at least ensure every section
has a valid header and size), printing (will always have an object to
get its data to at least hex dump), and re-flattening (no need to keep
around the original data buffer).
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I2b79feb4abc0f44179bdb8eab950f0d274e4e472
-rw-r--r-- | extensions/openpower-pels/generic.cpp | 55 | ||||
-rw-r--r-- | extensions/openpower-pels/generic.hpp | 87 | ||||
-rw-r--r-- | extensions/openpower-pels/openpower-pels.mk | 1 | ||||
-rw-r--r-- | test/openpower-pels/Makefile.include | 10 | ||||
-rw-r--r-- | test/openpower-pels/generic_section_test.cpp | 49 |
5 files changed, 202 insertions, 0 deletions
diff --git a/extensions/openpower-pels/generic.cpp b/extensions/openpower-pels/generic.cpp new file mode 100644 index 0000000..78d9e81 --- /dev/null +++ b/extensions/openpower-pels/generic.cpp @@ -0,0 +1,55 @@ +#include "generic.hpp" + +#include <phosphor-logging/log.hpp> + +namespace openpower +{ +namespace pels +{ + +using namespace phosphor::logging; + +void Generic::unflatten(Stream& stream) +{ + stream >> _header; + + if (_header.size <= SectionHeader::flattenedSize()) + { + throw std::out_of_range( + "Generic::unflatten: SectionHeader::size field too small"); + } + + size_t dataLength = _header.size - SectionHeader::flattenedSize(); + _data.resize(dataLength); + + stream >> _data; +} + +void Generic::flatten(Stream& stream) +{ + stream << _header << _data; +} + +Generic::Generic(Stream& pel) +{ + try + { + unflatten(pel); + validate(); + } + catch (const std::exception& e) + { + log<level::ERR>("Cannot unflatten generic section", + entry("ERROR=%s", e.what())); + _valid = false; + } +} + +void Generic::validate() +{ + // Nothing to validate + _valid = true; +} + +} // namespace pels +} // namespace openpower diff --git a/extensions/openpower-pels/generic.hpp b/extensions/openpower-pels/generic.hpp new file mode 100644 index 0000000..892e249 --- /dev/null +++ b/extensions/openpower-pels/generic.hpp @@ -0,0 +1,87 @@ +#pragma once + +#include "section.hpp" +#include "stream.hpp" + +namespace openpower +{ +namespace pels +{ + +/** + * @class Generic + * + * This class is used for a PEL section when there is no other class to use. + * It just contains a vector of the raw data. Its purpose is so that a PEL + * can be completely unflattened even if the code doesn't have a class for + * every section type. + */ +class Generic : public Section +{ + public: + Generic() = delete; + ~Generic() = default; + Generic(const Generic&) = default; + Generic& operator=(const Generic&) = default; + Generic(Generic&&) = default; + Generic& operator=(Generic&&) = default; + + /** + * @brief Constructor + * + * Fills in this class's data fields from the stream. + * + * @param[in] pel - the PEL data stream + */ + explicit Generic(Stream& pel); + + /** + * @brief Flatten the section into the stream + * + * @param[in] stream - The stream to write to + */ + void flatten(Stream& stream) override; + + /** + * @brief Returns the size of this section when flattened into a PEL + * + * @return size_t - the size of the section + */ + size_t flattenedSize() + { + return Section::flattenedSize() + _data.size(); + } + + /** + * @brief Returns the raw section data + * + * @return std::vector<uint8_t>& + */ + const std::vector<uint8_t>& data() const + { + return _data; + } + + private: + /** + * @brief Fills in the object from the stream data + * + * @param[in] stream - The stream to read from + */ + void unflatten(Stream& stream); + + /** + * @brief Validates the section contents + * + * Updates _valid (in Section) with the results. + */ + void validate() override; + + /** + * @brief The section data + */ + std::vector<uint8_t> _data; +}; + +} // namespace pels +} // namespace openpower diff --git a/extensions/openpower-pels/openpower-pels.mk b/extensions/openpower-pels/openpower-pels.mk index 89143b2..f1603b6 100644 --- a/extensions/openpower-pels/openpower-pels.mk +++ b/extensions/openpower-pels/openpower-pels.mk @@ -3,6 +3,7 @@ phosphor_log_manager_SOURCES += \ extensions/openpower-pels/data_interface.cpp \ extensions/openpower-pels/entry_points.cpp \ extensions/openpower-pels/failing_mtms.cpp \ + extensions/openpower-pels/generic.cpp \ extensions/openpower-pels/log_id.cpp \ extensions/openpower-pels/manager.cpp \ extensions/openpower-pels/mtms.cpp \ diff --git a/test/openpower-pels/Makefile.include b/test/openpower-pels/Makefile.include index e6f08e2..611a2fa 100644 --- a/test/openpower-pels/Makefile.include +++ b/test/openpower-pels/Makefile.include @@ -4,6 +4,7 @@ check_PROGRAMS += \ additional_data_test \ bcd_time_test \ failing_mtms_test \ + generic_section_test \ log_id_test \ mtms_test \ pel_test \ @@ -155,3 +156,12 @@ pel_values_test_LDADD = \ $(test_ldflags) \ $(top_builddir)/extensions/openpower-pels/pel_values.o pel_values_test_LDFLAGS = $(test_ldflags) + +generic_section_test_SOURCES = \ + %reldir%/generic_section_test.cpp %reldir%/pel_utils.cpp +generic_section_test_CPPFLAGS = $(test_cppflags) +generic_section_test_CXXFLAGS = $(test_cxxflags) +generic_section_test_LDADD = \ + $(test_ldadd) \ + $(top_builddir)/extensions/openpower-pels/generic.o +generic_section_test_LDFLAGS = $(test_ldflags) diff --git a/test/openpower-pels/generic_section_test.cpp b/test/openpower-pels/generic_section_test.cpp new file mode 100644 index 0000000..9fb6d9a --- /dev/null +++ b/test/openpower-pels/generic_section_test.cpp @@ -0,0 +1,49 @@ +#include "extensions/openpower-pels/generic.hpp" +#include "pel_utils.hpp" + +#include <gtest/gtest.h> + +using namespace openpower::pels; + +TEST(GenericSectionTest, UnflattenFlattenTest) +{ + // Use the private header data + auto data = pelDataFactory(TestPelType::privateHeaderSimple); + + Stream stream(*data); + Generic section(stream); + + EXPECT_EQ(section.header().id, 0x5048); + EXPECT_EQ(section.header().size, data->size()); + EXPECT_EQ(section.header().version, 0x01); + EXPECT_EQ(section.header().subType, 0x02); + EXPECT_EQ(section.header().componentID, 0x0304); + + const auto& sectionData = section.data(); + + // The data itself starts after the header + EXPECT_EQ(sectionData.size(), data->size() - 8); + + for (size_t i = 0; i < sectionData.size(); i++) + { + EXPECT_EQ(sectionData[i], (*data)[i + 8]); + } + + // Now flatten + std::vector<uint8_t> newData; + Stream newStream(newData); + section.flatten(newStream); + + EXPECT_EQ(*data, newData); +} + +TEST(GenericSectionTest, BadDataTest) +{ + // Use the private header data to start with + auto data = pelDataFactory(TestPelType::privateHeaderSimple); + data->resize(4); + + Stream stream(*data); + Generic section(stream); + ASSERT_FALSE(section.valid()); +} |