1 /**
2 * Copyright © 2019 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 "user_data.hpp"
17
18 #include "json_utils.hpp"
19 #include "pel_types.hpp"
20 #include "user_data_formats.hpp"
21 #ifdef PELTOOL
22 #include "user_data_json.hpp"
23 #endif
24
25 #include <phosphor-logging/lg2.hpp>
26
27 #include <format>
28
29 namespace openpower
30 {
31 namespace pels
32 {
33
unflatten(Stream & stream)34 void UserData::unflatten(Stream& stream)
35 {
36 stream >> _header;
37
38 if (_header.size <= SectionHeader::flattenedSize())
39 {
40 throw std::out_of_range(
41 "UserData::unflatten: SectionHeader::size field too small");
42 }
43
44 size_t dataLength = _header.size - SectionHeader::flattenedSize();
45 _data.resize(dataLength);
46
47 stream >> _data;
48 }
49
flatten(Stream & stream) const50 void UserData::flatten(Stream& stream) const
51 {
52 stream << _header << _data;
53 }
54
UserData(Stream & pel)55 UserData::UserData(Stream& pel)
56 {
57 try
58 {
59 unflatten(pel);
60 validate();
61 }
62 catch (const std::exception& e)
63 {
64 lg2::error("Cannot unflatten user data: {EXCEPTION}", "EXCEPTION", e);
65 _valid = false;
66 }
67 }
68
UserData(uint16_t componentID,uint8_t subType,uint8_t version,const std::vector<uint8_t> & data)69 UserData::UserData(uint16_t componentID, uint8_t subType, uint8_t version,
70 const std::vector<uint8_t>& data)
71 {
72 _header.id = static_cast<uint16_t>(SectionID::userData);
73 _header.size = Section::flattenedSize() + data.size();
74 _header.version = version;
75 _header.subType = subType;
76 _header.componentID = componentID;
77
78 _data = data;
79
80 _valid = true;
81 }
82
validate()83 void UserData::validate()
84 {
85 if (header().id != static_cast<uint16_t>(SectionID::userData))
86 {
87 lg2::error("Invalid UserData section ID: {HEADER_ID}", "HEADER_ID",
88 lg2::hex, header().id);
89 _valid = false;
90 }
91 else
92 {
93 _valid = true;
94 }
95 }
96
getJSON(uint8_t creatorID,const std::vector<std::string> & plugins) const97 std::optional<std::string> UserData::getJSON(
98 uint8_t creatorID [[maybe_unused]],
99 const std::vector<std::string>& plugins [[maybe_unused]]) const
100 {
101 #ifdef PELTOOL
102 return user_data::getJSON(_header.componentID, _header.subType,
103 _header.version, _data, creatorID, plugins);
104 #endif
105 return std::nullopt;
106 }
107
shrink(size_t newSize)108 bool UserData::shrink(size_t newSize)
109 {
110 // minimum size is 4 bytes plus the 8B header
111 if ((newSize < flattenedSize()) &&
112 (newSize >= (Section::flattenedSize() + 4)))
113 {
114 auto dataSize = newSize - Section::flattenedSize();
115
116 // Ensure it's 4B aligned
117 _data.resize((dataSize / 4) * 4);
118 _header.size = Section::flattenedSize() + _data.size();
119 return true;
120 }
121
122 return false;
123 }
124
125 } // namespace pels
126 } // namespace openpower
127