blob: 0731b604a80520685c6f8cf360c996eef4c698c6 [file] [log] [blame]
Matt Spinler386a61e2020-08-13 15:51:12 -05001/**
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 <fmt/format.h>
23
24#include <phosphor-logging/log.hpp>
25
26namespace openpower::pels
27{
28
29using namespace phosphor::logging;
30
31void ExtendedUserData::unflatten(Stream& stream)
32{
33 stream >> _header;
34
35 if (_header.size <= SectionHeader::flattenedSize() + 4)
36 {
37 throw std::out_of_range(
38 fmt::format("ExtendedUserData::unflatten: SectionHeader::size {} "
39 "too small",
40 _header.size));
41 }
42
43 size_t dataLength = _header.size - 4 - SectionHeader::flattenedSize();
44 _data.resize(dataLength);
45
46 stream >> _creatorID >> _reserved1B >> _reserved2B >> _data;
47}
48
49void ExtendedUserData::flatten(Stream& stream) const
50{
51 stream << _header << _creatorID << _reserved1B << _reserved2B << _data;
52}
53
54ExtendedUserData::ExtendedUserData(Stream& pel)
55{
56 try
57 {
58 unflatten(pel);
59 validate();
60 }
61 catch (const std::exception& e)
62 {
63 log<level::ERR>(
64 fmt::format("Cannot unflatten ExtendedUserData: {}", e.what())
65 .c_str());
66 _valid = false;
67 }
68}
69
70ExtendedUserData::ExtendedUserData(uint16_t componentID, uint8_t subType,
71 uint8_t version, uint8_t creatorID,
72 const std::vector<uint8_t>& data)
73{
74 _header.id = static_cast<uint16_t>(SectionID::extUserData);
75 _header.version = version;
76 _header.subType = subType;
77 _header.componentID = componentID;
78
79 _creatorID = creatorID;
80 _reserved1B = 0;
81 _reserved2B = 0;
82 _data = data;
83 _header.size = flattenedSize();
84 _valid = true;
85}
86
87void ExtendedUserData::validate()
88{
89 if (header().id != static_cast<uint16_t>(SectionID::extUserData))
90 {
91 log<level::ERR>(
92 fmt::format("Invalid ExtendedUserData section ID {}", header().id)
93 .c_str());
94 _valid = false;
95 }
96 else
97 {
98 _valid = true;
99 }
100}
101
102std::optional<std::string>
103 ExtendedUserData::getJSON(uint8_t creatorID,
104 const std::vector<std::string>& plugins) const
105{
106 // Use the creator ID value from the section.
107#ifdef PELTOOL
108 return user_data::getJSON(_header.componentID, _header.subType,
109 _header.version, _data, _creatorID, plugins);
110#endif
111 return std::nullopt;
112}
113
114bool ExtendedUserData::shrink(size_t newSize)
115{
116 // minimum size is 8B header + 4B of fields + 4B of data
117 if ((newSize < flattenedSize()) &&
118 (newSize >= (Section::flattenedSize() + 8)))
119 {
120 auto dataSize = newSize - Section::flattenedSize() - 4;
121
122 // Ensure it's 4B aligned
123 _data.resize((dataSize / 4) * 4);
124 _header.size = flattenedSize();
125 return true;
126 }
127
128 return false;
129}
130
131} // namespace openpower::pels