1711d51d8SMatt Spinler /**
2711d51d8SMatt Spinler * Copyright © 2019 IBM Corporation
3711d51d8SMatt Spinler *
4711d51d8SMatt Spinler * Licensed under the Apache License, Version 2.0 (the "License");
5711d51d8SMatt Spinler * you may not use this file except in compliance with the License.
6711d51d8SMatt Spinler * You may obtain a copy of the License at
7711d51d8SMatt Spinler *
8711d51d8SMatt Spinler * http://www.apache.org/licenses/LICENSE-2.0
9711d51d8SMatt Spinler *
10711d51d8SMatt Spinler * Unless required by applicable law or agreed to in writing, software
11711d51d8SMatt Spinler * distributed under the License is distributed on an "AS IS" BASIS,
12711d51d8SMatt Spinler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13711d51d8SMatt Spinler * See the License for the specific language governing permissions and
14711d51d8SMatt Spinler * limitations under the License.
15711d51d8SMatt Spinler */
1651c9263fSAatir Manzur #include "user_data.hpp"
1751c9263fSAatir Manzur
18acb7c106SMatt Spinler #include "json_utils.hpp"
1951c9263fSAatir Manzur #include "pel_types.hpp"
20acb7c106SMatt Spinler #include "user_data_formats.hpp"
21acb7c106SMatt Spinler #ifdef PELTOOL
22acb7c106SMatt Spinler #include "user_data_json.hpp"
23acb7c106SMatt Spinler #endif
2451c9263fSAatir Manzur
255bc26533SArya K Padman #include <phosphor-logging/lg2.hpp>
2651c9263fSAatir Manzur
271aa90d49SJayanth Othayoth #include <format>
281aa90d49SJayanth Othayoth
2951c9263fSAatir Manzur namespace openpower
3051c9263fSAatir Manzur {
3151c9263fSAatir Manzur namespace pels
3251c9263fSAatir Manzur {
3351c9263fSAatir Manzur
unflatten(Stream & stream)3451c9263fSAatir Manzur void UserData::unflatten(Stream& stream)
3551c9263fSAatir Manzur {
3651c9263fSAatir Manzur stream >> _header;
3751c9263fSAatir Manzur
3851c9263fSAatir Manzur if (_header.size <= SectionHeader::flattenedSize())
3951c9263fSAatir Manzur {
4051c9263fSAatir Manzur throw std::out_of_range(
4151c9263fSAatir Manzur "UserData::unflatten: SectionHeader::size field too small");
4251c9263fSAatir Manzur }
4351c9263fSAatir Manzur
4451c9263fSAatir Manzur size_t dataLength = _header.size - SectionHeader::flattenedSize();
4551c9263fSAatir Manzur _data.resize(dataLength);
4651c9263fSAatir Manzur
4751c9263fSAatir Manzur stream >> _data;
4851c9263fSAatir Manzur }
4951c9263fSAatir Manzur
flatten(Stream & stream) const500688545bSMatt Spinler void UserData::flatten(Stream& stream) const
5151c9263fSAatir Manzur {
5251c9263fSAatir Manzur stream << _header << _data;
5351c9263fSAatir Manzur }
5451c9263fSAatir Manzur
UserData(Stream & pel)5551c9263fSAatir Manzur UserData::UserData(Stream& pel)
5651c9263fSAatir Manzur {
5751c9263fSAatir Manzur try
5851c9263fSAatir Manzur {
5951c9263fSAatir Manzur unflatten(pel);
6051c9263fSAatir Manzur validate();
6151c9263fSAatir Manzur }
6251c9263fSAatir Manzur catch (const std::exception& e)
6351c9263fSAatir Manzur {
645bc26533SArya K Padman lg2::error("Cannot unflatten user data: {EXCEPTION}", "EXCEPTION", e);
6551c9263fSAatir Manzur _valid = false;
6651c9263fSAatir Manzur }
6751c9263fSAatir Manzur }
6851c9263fSAatir Manzur
UserData(uint16_t componentID,uint8_t subType,uint8_t version,const std::vector<uint8_t> & data)6951c9263fSAatir Manzur UserData::UserData(uint16_t componentID, uint8_t subType, uint8_t version,
7051c9263fSAatir Manzur const std::vector<uint8_t>& data)
7151c9263fSAatir Manzur {
7251c9263fSAatir Manzur _header.id = static_cast<uint16_t>(SectionID::userData);
7351c9263fSAatir Manzur _header.size = Section::flattenedSize() + data.size();
7451c9263fSAatir Manzur _header.version = version;
7551c9263fSAatir Manzur _header.subType = subType;
7651c9263fSAatir Manzur _header.componentID = componentID;
7751c9263fSAatir Manzur
7851c9263fSAatir Manzur _data = data;
7951c9263fSAatir Manzur
8051c9263fSAatir Manzur _valid = true;
8151c9263fSAatir Manzur }
8251c9263fSAatir Manzur
validate()8351c9263fSAatir Manzur void UserData::validate()
8451c9263fSAatir Manzur {
8551c9263fSAatir Manzur if (header().id != static_cast<uint16_t>(SectionID::userData))
8651c9263fSAatir Manzur {
875bc26533SArya K Padman lg2::error("Invalid UserData section ID: {HEADER_ID}", "HEADER_ID",
885bc26533SArya K Padman lg2::hex, header().id);
8951c9263fSAatir Manzur _valid = false;
9051c9263fSAatir Manzur }
9151c9263fSAatir Manzur else
9251c9263fSAatir Manzur {
9351c9263fSAatir Manzur _valid = true;
9451c9263fSAatir Manzur }
9551c9263fSAatir Manzur }
9651c9263fSAatir Manzur
getJSON(uint8_t creatorID,const std::vector<std::string> & plugins) const97*075c7923SPatrick Williams std::optional<std::string> UserData::getJSON(
98*075c7923SPatrick Williams uint8_t creatorID [[maybe_unused]],
99*075c7923SPatrick Williams const std::vector<std::string>& plugins [[maybe_unused]]) const
100acb7c106SMatt Spinler {
101acb7c106SMatt Spinler #ifdef PELTOOL
102acb7c106SMatt Spinler return user_data::getJSON(_header.componentID, _header.subType,
1033fdcd4e8SHarisuddin Mohamed Isa _header.version, _data, creatorID, plugins);
104acb7c106SMatt Spinler #endif
105acb7c106SMatt Spinler return std::nullopt;
106acb7c106SMatt Spinler }
107acb7c106SMatt Spinler
shrink(size_t newSize)108cbf3c4d4SMatt Spinler bool UserData::shrink(size_t newSize)
109cbf3c4d4SMatt Spinler {
110cbf3c4d4SMatt Spinler // minimum size is 4 bytes plus the 8B header
111cbf3c4d4SMatt Spinler if ((newSize < flattenedSize()) &&
112cbf3c4d4SMatt Spinler (newSize >= (Section::flattenedSize() + 4)))
113cbf3c4d4SMatt Spinler {
114cbf3c4d4SMatt Spinler auto dataSize = newSize - Section::flattenedSize();
115cbf3c4d4SMatt Spinler
116cbf3c4d4SMatt Spinler // Ensure it's 4B aligned
117cbf3c4d4SMatt Spinler _data.resize((dataSize / 4) * 4);
118cbf3c4d4SMatt Spinler _header.size = Section::flattenedSize() + _data.size();
119cbf3c4d4SMatt Spinler return true;
120cbf3c4d4SMatt Spinler }
121cbf3c4d4SMatt Spinler
122cbf3c4d4SMatt Spinler return false;
123cbf3c4d4SMatt Spinler }
124cbf3c4d4SMatt Spinler
12551c9263fSAatir Manzur } // namespace pels
12651c9263fSAatir Manzur } // namespace openpower
127