| #pragma once |
| |
| #include "section.hpp" |
| #include "stream.hpp" |
| |
| namespace openpower::pels |
| { |
| |
| /** |
| * @class ExtendedUserData |
| * |
| * This represents the Extended User Data section in a PEL. It is free form |
| * data that the creator knows the contents of. The component ID, version, and |
| * sub-type fields in the section header are used to identify the format. |
| * |
| * This section is used for one subsystem to add FFDC data to a PEL created |
| * by another subsystem. It is basically the same as a UserData section, |
| * except it has the creator ID of the section creator stored in the section. |
| * |
| * The Section base class handles the section header structure that every |
| * PEL section has at offset zero. |
| */ |
| class ExtendedUserData : public Section |
| { |
| public: |
| ExtendedUserData() = delete; |
| ~ExtendedUserData() = default; |
| ExtendedUserData(const ExtendedUserData&) = default; |
| ExtendedUserData& operator=(const ExtendedUserData&) = default; |
| ExtendedUserData(ExtendedUserData&&) = default; |
| ExtendedUserData& operator=(ExtendedUserData&&) = default; |
| |
| /** |
| * @brief Constructor |
| * |
| * Fills in this class's data fields from the stream. |
| * |
| * @param[in] pel - the PEL data stream |
| */ |
| explicit ExtendedUserData(Stream& pel); |
| |
| /** |
| * @brief Constructor |
| * |
| * Create a valid ExtendedUserData object with the passed in data. |
| * |
| * The component ID, subtype, and version are used to identify |
| * the data to know which parser to call. |
| * |
| * @param[in] componentID - Component ID of the creator |
| * @param[in] subType - The type of user data |
| * @param[in] version - The version of the data |
| */ |
| ExtendedUserData(uint16_t componentID, uint8_t subType, uint8_t version, |
| uint8_t creatorID, const std::vector<uint8_t>& data); |
| |
| /** |
| * @brief Flatten the section into the stream |
| * |
| * @param[in] stream - The stream to write to |
| */ |
| void flatten(Stream& stream) const 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() + sizeof(_creatorID) + |
| sizeof(_reserved1B) + sizeof(_reserved2B) + _data.size(); |
| } |
| |
| /** |
| * @brief Returns the section creator ID field. |
| * |
| * @return uint8_t - The creator ID |
| */ |
| uint8_t creatorID() const |
| { |
| return _creatorID; |
| } |
| |
| /** |
| * @brief Returns the raw section data |
| * |
| * This doesn't include the creator ID. |
| * |
| * @return std::vector<uint8_t>& |
| */ |
| const std::vector<uint8_t>& data() const |
| { |
| return _data; |
| } |
| |
| /** |
| * @brief Returns the section data updated with new data |
| * |
| * @param[in] subType - The type of user data |
| * @param[in] componentID - Component ID of the creator |
| * @param[in] newData - The new data |
| * |
| */ |
| void updateDataSection(const uint8_t subType, const uint16_t componentId, |
| const std::vector<uint8_t>& newData) |
| { |
| auto origDataSize = 0; |
| |
| if (newData.size() >= 4) |
| { |
| // Update component Id & subtype in section header of ED |
| _header.componentID = static_cast<uint16_t>(componentId); |
| _header.subType = static_cast<uint8_t>(subType); |
| |
| if (newData.size() > _data.size()) |
| { |
| // Don't allow section to get bigger |
| origDataSize = _data.size(); |
| _data = newData; |
| _data.resize(origDataSize); |
| } |
| else |
| { |
| // Use shrink to handle 4B alignment and update the header size |
| auto status = |
| shrink(Section::flattenedSize() + 4 + newData.size()); |
| if (status) |
| { |
| origDataSize = _data.size(); |
| _data = newData; |
| _data.resize(origDataSize); |
| } |
| } |
| } |
| } |
| |
| /** |
| * @brief Get the section contents in JSON |
| * |
| * @param[in] creatorID - Creator Subsystem ID - unused (see the .cpp) |
| * @param[in] plugins - Vector of strings of plugins found in filesystem |
| * |
| * @return The JSON as a string if a parser was found, |
| * otherwise std::nullopt. |
| */ |
| std::optional<std::string> |
| getJSON(uint8_t creatorID, |
| const std::vector<std::string>& plugins) const override; |
| |
| /** |
| * @brief Shrink the section |
| * |
| * The new size must be between the current size and the minimum |
| * size, which is 12 bytes. If it isn't a 4 byte aligned value |
| * the code will do the aligning before the resize takes place. |
| * |
| * @param[in] newSize - The new size in bytes |
| * |
| * @return bool - true if successful, false else. |
| */ |
| bool shrink(size_t newSize) override; |
| |
| 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 subsystem creator ID of the code that |
| * created this section. |
| */ |
| uint8_t _creatorID; |
| |
| /** |
| * @brief Reserved |
| */ |
| uint8_t _reserved1B; |
| |
| /** |
| * @brief Reserved |
| */ |
| uint16_t _reserved2B; |
| |
| /** |
| * @brief The section data |
| */ |
| std::vector<uint8_t> _data; |
| }; |
| |
| } // namespace openpower::pels |