xref: /openbmc/phosphor-logging/extensions/openpower-pels/user_data.cpp (revision 40fb54935ce7367636a7156039396ee91cc4d5e2)
1 // SPDX-License-Identifier: Apache-2.0
2 // SPDX-FileCopyrightText: Copyright 2019 IBM Corporation
3 
4 #include "user_data.hpp"
5 
6 #include "pel_types.hpp"
7 #ifdef PELTOOL
8 #include "user_data_json.hpp"
9 #endif
10 
11 #include <phosphor-logging/lg2.hpp>
12 
13 namespace openpower
14 {
15 namespace pels
16 {
17 
unflatten(Stream & stream)18 void UserData::unflatten(Stream& stream)
19 {
20     stream >> _header;
21 
22     if (_header.size <= SectionHeader::flattenedSize())
23     {
24         throw std::out_of_range(
25             "UserData::unflatten: SectionHeader::size field too small");
26     }
27 
28     size_t dataLength = _header.size - SectionHeader::flattenedSize();
29     _data.resize(dataLength);
30 
31     stream >> _data;
32 }
33 
flatten(Stream & stream) const34 void UserData::flatten(Stream& stream) const
35 {
36     stream << _header << _data;
37 }
38 
UserData(Stream & pel)39 UserData::UserData(Stream& pel)
40 {
41     try
42     {
43         unflatten(pel);
44         validate();
45     }
46     catch (const std::exception& e)
47     {
48         lg2::error("Cannot unflatten user data: {EXCEPTION}", "EXCEPTION", e);
49         _valid = false;
50     }
51 }
52 
UserData(uint16_t componentID,uint8_t subType,uint8_t version,const std::vector<uint8_t> & data)53 UserData::UserData(uint16_t componentID, uint8_t subType, uint8_t version,
54                    const std::vector<uint8_t>& data)
55 {
56     _header.id = static_cast<uint16_t>(SectionID::userData);
57     _header.size = Section::headerSize() + data.size();
58     _header.version = version;
59     _header.subType = subType;
60     _header.componentID = componentID;
61 
62     _data = data;
63 
64     _valid = true;
65 }
66 
validate()67 void UserData::validate()
68 {
69     if (header().id != static_cast<uint16_t>(SectionID::userData))
70     {
71         lg2::error("Invalid UserData section ID: {HEADER_ID}", "HEADER_ID",
72                    lg2::hex, header().id);
73         _valid = false;
74     }
75     else
76     {
77         _valid = true;
78     }
79 }
80 
getJSON(uint8_t creatorID,const std::vector<std::string> & plugins) const81 std::optional<std::string> UserData::getJSON(
82     uint8_t creatorID [[maybe_unused]],
83     const std::vector<std::string>& plugins [[maybe_unused]]) const
84 {
85 #ifdef PELTOOL
86     return user_data::getJSON(_header.componentID, _header.subType,
87                               _header.version, _data, creatorID, plugins);
88 #endif
89     return std::nullopt;
90 }
91 
shrink(size_t newSize)92 bool UserData::shrink(size_t newSize)
93 {
94     // minimum size is 4 bytes plus the 8B header
95     if ((newSize < flattenedSize()) && (newSize >= (Section::headerSize() + 4)))
96     {
97         auto dataSize = newSize - Section::headerSize();
98 
99         // Ensure it's 4B aligned
100         _data.resize((dataSize / 4) * 4);
101         _header.size = Section::headerSize() + _data.size();
102         return true;
103     }
104 
105     return false;
106 }
107 
108 } // namespace pels
109 } // namespace openpower
110