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