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