1 /** 2 * Copyright © 2020 IBM Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #include "extended_user_data.hpp" 17 18 #include "pel_types.hpp" 19 #ifdef PELTOOL 20 #include "user_data_json.hpp" 21 #endif 22 #include <phosphor-logging/lg2.hpp> 23 24 #include <format> 25 26 namespace openpower::pels 27 { 28 29 void ExtendedUserData::unflatten(Stream& stream) 30 { 31 stream >> _header; 32 33 if (_header.size <= SectionHeader::flattenedSize() + 4) 34 { 35 throw std::out_of_range( 36 std::format("ExtendedUserData::unflatten: SectionHeader::size {} " 37 "too small", 38 _header.size)); 39 } 40 41 size_t dataLength = _header.size - 4 - SectionHeader::flattenedSize(); 42 _data.resize(dataLength); 43 44 stream >> _creatorID >> _reserved1B >> _reserved2B >> _data; 45 } 46 47 void ExtendedUserData::flatten(Stream& stream) const 48 { 49 stream << _header << _creatorID << _reserved1B << _reserved2B << _data; 50 } 51 52 ExtendedUserData::ExtendedUserData(Stream& pel) 53 { 54 try 55 { 56 unflatten(pel); 57 validate(); 58 } 59 catch (const std::exception& e) 60 { 61 lg2::error("Cannot unflatten ExtendedUserData section: {EXCEPTION}", 62 "EXCEPTION", e); 63 _valid = false; 64 } 65 } 66 67 ExtendedUserData::ExtendedUserData(uint16_t componentID, uint8_t subType, 68 uint8_t version, uint8_t creatorID, 69 const std::vector<uint8_t>& data) 70 { 71 _header.id = static_cast<uint16_t>(SectionID::extUserData); 72 _header.version = version; 73 _header.subType = subType; 74 _header.componentID = componentID; 75 76 _creatorID = creatorID; 77 _reserved1B = 0; 78 _reserved2B = 0; 79 _data = data; 80 _header.size = flattenedSize(); 81 _valid = true; 82 } 83 84 void ExtendedUserData::validate() 85 { 86 if (header().id != static_cast<uint16_t>(SectionID::extUserData)) 87 { 88 lg2::error("Invalid ExtendedUserData section ID: {HEADER_ID}", 89 "HEADER_ID", lg2::hex, header().id); 90 _valid = false; 91 } 92 else 93 { 94 _valid = true; 95 } 96 } 97 98 std::optional<std::string> ExtendedUserData::getJSON( 99 uint8_t /*creatorID*/, 100 const std::vector<std::string>& plugins [[maybe_unused]]) const 101 { 102 // Use the creator ID value from the section. 103 #ifdef PELTOOL 104 return user_data::getJSON(_header.componentID, _header.subType, 105 _header.version, _data, _creatorID, plugins); 106 #endif 107 return std::nullopt; 108 } 109 110 bool ExtendedUserData::shrink(size_t newSize) 111 { 112 // minimum size is 8B header + 4B of fields + 4B of data 113 if ((newSize < flattenedSize()) && 114 (newSize >= (Section::flattenedSize() + 8))) 115 { 116 auto dataSize = newSize - Section::flattenedSize() - 4; 117 118 // Ensure it's 4B aligned 119 _data.resize((dataSize / 4) * 4); 120 _header.size = flattenedSize(); 121 return true; 122 } 123 124 return false; 125 } 126 127 } // namespace openpower::pels 128