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 "trace.hpp" 23 24 #include <fmt/format.h> 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 fmt::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 trace::error( 62 fmt::format("Cannot unflatten ExtendedUserData: {}", e.what())); 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 trace::error( 89 fmt::format("Invalid ExtendedUserData section ID {}", header().id)); 90 _valid = false; 91 } 92 else 93 { 94 _valid = true; 95 } 96 } 97 98 std::optional<std::string> 99 ExtendedUserData::getJSON(uint8_t /*creatorID*/, 100 const std::vector<std::string>& plugins 101 [[maybe_unused]]) const 102 { 103 // Use the creator ID value from the section. 104 #ifdef PELTOOL 105 return user_data::getJSON(_header.componentID, _header.subType, 106 _header.version, _data, _creatorID, plugins); 107 #endif 108 return std::nullopt; 109 } 110 111 bool ExtendedUserData::shrink(size_t newSize) 112 { 113 // minimum size is 8B header + 4B of fields + 4B of data 114 if ((newSize < flattenedSize()) && 115 (newSize >= (Section::flattenedSize() + 8))) 116 { 117 auto dataSize = newSize - Section::flattenedSize() - 4; 118 119 // Ensure it's 4B aligned 120 _data.resize((dataSize / 4) * 4); 121 _header.size = flattenedSize(); 122 return true; 123 } 124 125 return false; 126 } 127 128 } // namespace openpower::pels 129