1 #pragma once 2 3 #include "section.hpp" 4 #include "stream.hpp" 5 6 namespace openpower::pels 7 { 8 9 /** 10 * @class ExtendedUserData 11 * 12 * This represents the Extended User Data section in a PEL. It is free form 13 * data that the creator knows the contents of. The component ID, version, and 14 * sub-type fields in the section header are used to identify the format. 15 * 16 * This section is used for one subsystem to add FFDC data to a PEL created 17 * by another subsystem. It is basically the same as a UserData section, 18 * except it has the creator ID of the section creator stored in the section. 19 * 20 * The Section base class handles the section header structure that every 21 * PEL section has at offset zero. 22 */ 23 class ExtendedUserData : public Section 24 { 25 public: 26 ExtendedUserData() = delete; 27 ~ExtendedUserData() = default; 28 ExtendedUserData(const ExtendedUserData&) = default; 29 ExtendedUserData& operator=(const ExtendedUserData&) = default; 30 ExtendedUserData(ExtendedUserData&&) = default; 31 ExtendedUserData& operator=(ExtendedUserData&&) = default; 32 33 /** 34 * @brief Constructor 35 * 36 * Fills in this class's data fields from the stream. 37 * 38 * @param[in] pel - the PEL data stream 39 */ 40 explicit ExtendedUserData(Stream& pel); 41 42 /** 43 * @brief Constructor 44 * 45 * Create a valid ExtendedUserData object with the passed in data. 46 * 47 * The component ID, subtype, and version are used to identify 48 * the data to know which parser to call. 49 * 50 * @param[in] componentID - Component ID of the creator 51 * @param[in] subType - The type of user data 52 * @param[in] version - The version of the data 53 */ 54 ExtendedUserData(uint16_t componentID, uint8_t subType, uint8_t version, 55 uint8_t creatorID, const std::vector<uint8_t>& data); 56 57 /** 58 * @brief Flatten the section into the stream 59 * 60 * @param[in] stream - The stream to write to 61 */ 62 void flatten(Stream& stream) const override; 63 64 /** 65 * @brief Returns the size of this section when flattened into a PEL 66 * 67 * @return size_t - the size of the section 68 */ 69 size_t flattenedSize() 70 { 71 return Section::flattenedSize() + sizeof(_creatorID) + 72 sizeof(_reserved1B) + sizeof(_reserved2B) + _data.size(); 73 } 74 75 /** 76 * @brief Returns the section creator ID field. 77 * 78 * @return uint8_t - The creator ID 79 */ 80 uint8_t creatorID() const 81 { 82 return _creatorID; 83 } 84 85 /** 86 * @brief Returns the raw section data 87 * 88 * This doesn't include the creator ID. 89 * 90 * @return std::vector<uint8_t>& 91 */ 92 const std::vector<uint8_t>& data() const 93 { 94 return _data; 95 } 96 97 /** 98 * @brief Returns the section data updated with new data 99 * 100 * @param[in] subType - The type of user data 101 * @param[in] componentID - Component ID of the creator 102 * @param[in] newData - The new data 103 * 104 */ 105 void updateDataSection(const uint8_t subType, const uint16_t componentId, 106 const std::vector<uint8_t>& newData) 107 { 108 auto origDataSize = 0; 109 110 if (newData.size() >= 4) 111 { 112 // Update component Id & subtype in section header of ED 113 _header.componentID = static_cast<uint16_t>(componentId); 114 _header.subType = static_cast<uint8_t>(subType); 115 116 if (newData.size() > _data.size()) 117 { 118 // Don't allow section to get bigger 119 origDataSize = _data.size(); 120 _data = newData; 121 _data.resize(origDataSize); 122 } 123 else 124 { 125 // Use shrink to handle 4B alignment and update the header size 126 auto status = 127 shrink(Section::flattenedSize() + 4 + newData.size()); 128 if (status) 129 { 130 origDataSize = _data.size(); 131 _data = newData; 132 _data.resize(origDataSize); 133 } 134 } 135 } 136 } 137 138 /** 139 * @brief Get the section contents in JSON 140 * 141 * @param[in] creatorID - Creator Subsystem ID - unused (see the .cpp) 142 * @param[in] plugins - Vector of strings of plugins found in filesystem 143 * 144 * @return The JSON as a string if a parser was found, 145 * otherwise std::nullopt. 146 */ 147 std::optional<std::string> 148 getJSON(uint8_t creatorID, 149 const std::vector<std::string>& plugins) const override; 150 151 /** 152 * @brief Shrink the section 153 * 154 * The new size must be between the current size and the minimum 155 * size, which is 12 bytes. If it isn't a 4 byte aligned value 156 * the code will do the aligning before the resize takes place. 157 * 158 * @param[in] newSize - The new size in bytes 159 * 160 * @return bool - true if successful, false else. 161 */ 162 bool shrink(size_t newSize) override; 163 164 private: 165 /** 166 * @brief Fills in the object from the stream data 167 * 168 * @param[in] stream - The stream to read from 169 */ 170 void unflatten(Stream& stream); 171 172 /** 173 * @brief Validates the section contents 174 * 175 * Updates _valid (in Section) with the results. 176 */ 177 void validate() override; 178 179 /** 180 * @brief The subsystem creator ID of the code that 181 * created this section. 182 */ 183 uint8_t _creatorID; 184 185 /** 186 * @brief Reserved 187 */ 188 uint8_t _reserved1B; 189 190 /** 191 * @brief Reserved 192 */ 193 uint16_t _reserved2B; 194 195 /** 196 * @brief The section data 197 */ 198 std::vector<uint8_t> _data; 199 }; 200 201 } // namespace openpower::pels 202