xref: /openbmc/phosphor-logging/extensions/openpower-pels/user_data.cpp (revision 8a09b982ddeb0c1e13190d9cd196e06a778d6140)
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