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