1fa5e4d32SSunny Srivastava #pragma once
2fa5e4d32SSunny Srivastava
3fa5e4d32SSunny Srivastava #include "config.h"
4fa5e4d32SSunny Srivastava
5fa5e4d32SSunny Srivastava #include "constants.hpp"
6815c6029SSouvik Roy #include "event_logger.hpp"
7fa5e4d32SSunny Srivastava #include "exceptions.hpp"
8fa5e4d32SSunny Srivastava #include "logger.hpp"
9fa5e4d32SSunny Srivastava #include "types.hpp"
10fa5e4d32SSunny Srivastava
11fa5e4d32SSunny Srivastava #include <nlohmann/json.hpp>
12fa5e4d32SSunny Srivastava #include <utility/common_utility.hpp>
13fa5e4d32SSunny Srivastava #include <utility/dbus_utility.hpp>
14fa5e4d32SSunny Srivastava
15fa5e4d32SSunny Srivastava #include <filesystem>
16fa5e4d32SSunny Srivastava #include <fstream>
17fa5e4d32SSunny Srivastava #include <regex>
18815c6029SSouvik Roy #include <typeindex>
19fa5e4d32SSunny Srivastava
20fa5e4d32SSunny Srivastava namespace vpd
21fa5e4d32SSunny Srivastava {
22fa5e4d32SSunny Srivastava namespace vpdSpecificUtility
23fa5e4d32SSunny Srivastava {
24fa5e4d32SSunny Srivastava /**
25fa5e4d32SSunny Srivastava * @brief API to generate file name for bad VPD.
26fa5e4d32SSunny Srivastava *
27fa5e4d32SSunny Srivastava * For i2c eeproms - the pattern of the vpd-name will be
28fa5e4d32SSunny Srivastava * i2c-<bus-number>-<eeprom-address>.
29fa5e4d32SSunny Srivastava * For spi eeproms - the pattern of the vpd-name will be spi-<spi-number>.
30fa5e4d32SSunny Srivastava *
318fc1252eSSouvik Roy * @param[in] i_vpdFilePath - file path of the vpd.
328fc1252eSSouvik Roy *
338fc1252eSSouvik Roy * @return On success, returns generated file name, otherwise returns empty
348fc1252eSSouvik Roy * string.
35fa5e4d32SSunny Srivastava */
generateBadVPDFileName(const std::string & i_vpdFilePath)368fc1252eSSouvik Roy inline std::string generateBadVPDFileName(
378fc1252eSSouvik Roy const std::string& i_vpdFilePath) noexcept
38fa5e4d32SSunny Srivastava {
39*0f370434SSouvik Roy std::string l_badVpdFileName{constants::badVpdDir};
408fc1252eSSouvik Roy try
41fa5e4d32SSunny Srivastava {
428fc1252eSSouvik Roy if (i_vpdFilePath.find("i2c") != std::string::npos)
43fa5e4d32SSunny Srivastava {
448fc1252eSSouvik Roy l_badVpdFileName += "i2c-";
458fc1252eSSouvik Roy std::regex l_i2cPattern("(at24/)([0-9]+-[0-9]+)\\/");
468fc1252eSSouvik Roy std::smatch l_match;
478fc1252eSSouvik Roy if (std::regex_search(i_vpdFilePath, l_match, l_i2cPattern))
488fc1252eSSouvik Roy {
498fc1252eSSouvik Roy l_badVpdFileName += l_match.str(2);
50fa5e4d32SSunny Srivastava }
51fa5e4d32SSunny Srivastava }
528fc1252eSSouvik Roy else if (i_vpdFilePath.find("spi") != std::string::npos)
53fa5e4d32SSunny Srivastava {
548fc1252eSSouvik Roy std::regex l_spiPattern("((spi)[0-9]+)(.0)");
558fc1252eSSouvik Roy std::smatch l_match;
568fc1252eSSouvik Roy if (std::regex_search(i_vpdFilePath, l_match, l_spiPattern))
57fa5e4d32SSunny Srivastava {
588fc1252eSSouvik Roy l_badVpdFileName += l_match.str(1);
59fa5e4d32SSunny Srivastava }
60fa5e4d32SSunny Srivastava }
618fc1252eSSouvik Roy }
628fc1252eSSouvik Roy catch (const std::exception& l_ex)
638fc1252eSSouvik Roy {
648fc1252eSSouvik Roy l_badVpdFileName.clear();
658fc1252eSSouvik Roy logging::logMessage("Failed to generate bad VPD file name for [" +
668fc1252eSSouvik Roy i_vpdFilePath + "]. Error: " + l_ex.what());
678fc1252eSSouvik Roy }
688fc1252eSSouvik Roy return l_badVpdFileName;
69fa5e4d32SSunny Srivastava }
70fa5e4d32SSunny Srivastava
71fa5e4d32SSunny Srivastava /**
72fa5e4d32SSunny Srivastava * @brief API which dumps the broken/bad vpd in a directory.
73fa5e4d32SSunny Srivastava * When the vpd is bad, this API places the bad vpd file inside
74*0f370434SSouvik Roy * "/var/lib/vpd/dumps" in BMC, in order to collect bad VPD data as a part of
75*0f370434SSouvik Roy * user initiated BMC dump.
76fa5e4d32SSunny Srivastava *
77fa5e4d32SSunny Srivastava *
788fc1252eSSouvik Roy * @param[in] i_vpdFilePath - vpd file path
798fc1252eSSouvik Roy * @param[in] i_vpdVector - vpd vector
808fc1252eSSouvik Roy *
818fc1252eSSouvik Roy * @return On success returns 0, otherwise returns -1.
82fa5e4d32SSunny Srivastava */
dumpBadVpd(const std::string & i_vpdFilePath,const types::BinaryVector & i_vpdVector)838fc1252eSSouvik Roy inline int dumpBadVpd(const std::string& i_vpdFilePath,
848fc1252eSSouvik Roy const types::BinaryVector& i_vpdVector) noexcept
858fc1252eSSouvik Roy {
868fc1252eSSouvik Roy int l_rc{constants::FAILURE};
878fc1252eSSouvik Roy try
88fa5e4d32SSunny Srivastava {
89*0f370434SSouvik Roy std::filesystem::create_directory(constants::badVpdDir);
908fc1252eSSouvik Roy auto l_badVpdPath = generateBadVPDFileName(i_vpdFilePath);
91fa5e4d32SSunny Srivastava
928fc1252eSSouvik Roy if (l_badVpdPath.empty())
93fa5e4d32SSunny Srivastava {
948fc1252eSSouvik Roy throw std::runtime_error("Failed to generate bad VPD file name");
958fc1252eSSouvik Roy }
968fc1252eSSouvik Roy
978fc1252eSSouvik Roy if (std::filesystem::exists(l_badVpdPath))
98fa5e4d32SSunny Srivastava {
998fc1252eSSouvik Roy std::error_code l_ec;
1008fc1252eSSouvik Roy std::filesystem::remove(l_badVpdPath, l_ec);
1018fc1252eSSouvik Roy if (l_ec) // error code
1028fc1252eSSouvik Roy {
1038fc1252eSSouvik Roy const std::string l_errorMsg{
1048fc1252eSSouvik Roy "Error removing the existing broken vpd in " +
1058fc1252eSSouvik Roy l_badVpdPath +
1068fc1252eSSouvik Roy ". Error code : " + std::to_string(l_ec.value()) +
1078fc1252eSSouvik Roy ". Error message : " + l_ec.message()};
1088fc1252eSSouvik Roy
1098fc1252eSSouvik Roy throw std::runtime_error(l_errorMsg);
110fa5e4d32SSunny Srivastava }
111fa5e4d32SSunny Srivastava }
112fa5e4d32SSunny Srivastava
1138fc1252eSSouvik Roy std::ofstream l_badVpdFileStream(l_badVpdPath, std::ofstream::binary);
1148fc1252eSSouvik Roy if (!l_badVpdFileStream.is_open())
115fa5e4d32SSunny Srivastava {
116*0f370434SSouvik Roy const std::string l_errorMsg{
117*0f370434SSouvik Roy "Failed to open bad vpd file path [" + l_badVpdPath +
118*0f370434SSouvik Roy "]. Unable to dump the broken/bad vpd file."};
119*0f370434SSouvik Roy
120*0f370434SSouvik Roy throw std::runtime_error(l_errorMsg);
121fa5e4d32SSunny Srivastava }
122fa5e4d32SSunny Srivastava
1238fc1252eSSouvik Roy l_badVpdFileStream.write(
1248fc1252eSSouvik Roy reinterpret_cast<const char*>(i_vpdVector.data()),
1258fc1252eSSouvik Roy i_vpdVector.size());
1268fc1252eSSouvik Roy
1278fc1252eSSouvik Roy l_rc = constants::SUCCESS;
1288fc1252eSSouvik Roy }
1298fc1252eSSouvik Roy catch (const std::exception& l_ex)
1308fc1252eSSouvik Roy {
1318fc1252eSSouvik Roy logging::logMessage("Failed to dump bad VPD for [" + i_vpdFilePath +
1328fc1252eSSouvik Roy "]. Error: " + l_ex.what());
1338fc1252eSSouvik Roy }
1348fc1252eSSouvik Roy return l_rc;
135fa5e4d32SSunny Srivastava }
136fa5e4d32SSunny Srivastava
137fa5e4d32SSunny Srivastava /**
138fa5e4d32SSunny Srivastava * @brief An API to read value of a keyword.
139fa5e4d32SSunny Srivastava *
140fa5e4d32SSunny Srivastava *
141a55fcca1SSouvik Roy * @param[in] i_kwdValueMap - A map having Kwd value pair.
142a55fcca1SSouvik Roy * @param[in] i_kwd - keyword name.
143a55fcca1SSouvik Roy *
144a55fcca1SSouvik Roy * @return On success returns value of the keyword read from map, otherwise
145a55fcca1SSouvik Roy * returns empty string.
146fa5e4d32SSunny Srivastava */
getKwVal(const types::IPZKwdValueMap & i_kwdValueMap,const std::string & i_kwd)147a55fcca1SSouvik Roy inline std::string getKwVal(const types::IPZKwdValueMap& i_kwdValueMap,
148a55fcca1SSouvik Roy const std::string& i_kwd) noexcept
149fa5e4d32SSunny Srivastava {
150a55fcca1SSouvik Roy std::string l_kwdValue;
151a55fcca1SSouvik Roy try
152fa5e4d32SSunny Srivastava {
153a55fcca1SSouvik Roy if (i_kwd.empty())
154a55fcca1SSouvik Roy {
155fa5e4d32SSunny Srivastava throw std::runtime_error("Invalid parameters");
156fa5e4d32SSunny Srivastava }
157fa5e4d32SSunny Srivastava
158a55fcca1SSouvik Roy auto l_itrToKwd = i_kwdValueMap.find(i_kwd);
159a55fcca1SSouvik Roy if (l_itrToKwd != i_kwdValueMap.end())
160fa5e4d32SSunny Srivastava {
161a55fcca1SSouvik Roy l_kwdValue = l_itrToKwd->second;
162fa5e4d32SSunny Srivastava }
163a55fcca1SSouvik Roy else
164a55fcca1SSouvik Roy {
165fa5e4d32SSunny Srivastava throw std::runtime_error("Keyword not found");
166fa5e4d32SSunny Srivastava }
167a55fcca1SSouvik Roy }
168a55fcca1SSouvik Roy catch (const std::exception& l_ex)
169a55fcca1SSouvik Roy {
170a55fcca1SSouvik Roy logging::logMessage("Failed to get value for keyword [" + i_kwd +
171a55fcca1SSouvik Roy "]. Error : " + l_ex.what());
172a55fcca1SSouvik Roy }
173a55fcca1SSouvik Roy return l_kwdValue;
174a55fcca1SSouvik Roy }
175fa5e4d32SSunny Srivastava
176fa5e4d32SSunny Srivastava /**
177fa5e4d32SSunny Srivastava * @brief An API to process encoding of a keyword.
178fa5e4d32SSunny Srivastava *
179f277d6a7SSouvik Roy * @param[in] i_keyword - Keyword to be processed.
180f277d6a7SSouvik Roy * @param[in] i_encoding - Type of encoding.
181f277d6a7SSouvik Roy *
182fa5e4d32SSunny Srivastava * @return Value after being processed for encoded type.
183fa5e4d32SSunny Srivastava */
encodeKeyword(const std::string & i_keyword,const std::string & i_encoding)184f277d6a7SSouvik Roy inline std::string encodeKeyword(const std::string& i_keyword,
185f277d6a7SSouvik Roy const std::string& i_encoding) noexcept
186fa5e4d32SSunny Srivastava {
187fa5e4d32SSunny Srivastava // Default value is keyword value
188f277d6a7SSouvik Roy std::string l_result(i_keyword.begin(), i_keyword.end());
189f277d6a7SSouvik Roy try
190fa5e4d32SSunny Srivastava {
191f277d6a7SSouvik Roy if (i_encoding == "MAC")
192fa5e4d32SSunny Srivastava {
193f277d6a7SSouvik Roy l_result.clear();
194f277d6a7SSouvik Roy size_t l_firstByte = i_keyword[0];
195f277d6a7SSouvik Roy l_result += commonUtility::toHex(l_firstByte >> 4);
196f277d6a7SSouvik Roy l_result += commonUtility::toHex(l_firstByte & 0x0f);
197f277d6a7SSouvik Roy for (size_t i = 1; i < i_keyword.size(); ++i)
198f277d6a7SSouvik Roy {
199f277d6a7SSouvik Roy l_result += ":";
200f277d6a7SSouvik Roy l_result += commonUtility::toHex(i_keyword[i] >> 4);
201f277d6a7SSouvik Roy l_result += commonUtility::toHex(i_keyword[i] & 0x0f);
202fa5e4d32SSunny Srivastava }
203fa5e4d32SSunny Srivastava }
204f277d6a7SSouvik Roy else if (i_encoding == "DATE")
205fa5e4d32SSunny Srivastava {
206fa5e4d32SSunny Srivastava // Date, represent as
207fa5e4d32SSunny Srivastava // <year>-<month>-<day> <hour>:<min>
208f277d6a7SSouvik Roy l_result.clear();
209fa5e4d32SSunny Srivastava static constexpr uint8_t skipPrefix = 3;
210fa5e4d32SSunny Srivastava
211f277d6a7SSouvik Roy auto strItr = i_keyword.begin();
212fa5e4d32SSunny Srivastava advance(strItr, skipPrefix);
213f277d6a7SSouvik Roy for_each(strItr, i_keyword.end(),
214f277d6a7SSouvik Roy [&l_result](size_t c) { l_result += c; });
215fa5e4d32SSunny Srivastava
216f277d6a7SSouvik Roy l_result.insert(constants::BD_YEAR_END, 1, '-');
217f277d6a7SSouvik Roy l_result.insert(constants::BD_MONTH_END, 1, '-');
218f277d6a7SSouvik Roy l_result.insert(constants::BD_DAY_END, 1, ' ');
219f277d6a7SSouvik Roy l_result.insert(constants::BD_HOUR_END, 1, ':');
220f277d6a7SSouvik Roy }
221f277d6a7SSouvik Roy }
222f277d6a7SSouvik Roy catch (const std::exception& l_ex)
223f277d6a7SSouvik Roy {
224f277d6a7SSouvik Roy l_result.clear();
225f277d6a7SSouvik Roy logging::logMessage("Failed to encode keyword [" + i_keyword +
226f277d6a7SSouvik Roy "]. Error: " + l_ex.what());
227fa5e4d32SSunny Srivastava }
228fa5e4d32SSunny Srivastava
229f277d6a7SSouvik Roy return l_result;
230fa5e4d32SSunny Srivastava }
231fa5e4d32SSunny Srivastava
232fa5e4d32SSunny Srivastava /**
233fa5e4d32SSunny Srivastava * @brief Helper function to insert or merge in map.
234fa5e4d32SSunny Srivastava *
235fa5e4d32SSunny Srivastava * This method checks in an interface if the given interface exists. If the
236fa5e4d32SSunny Srivastava * interface key already exists, property map is inserted corresponding to it.
237fa5e4d32SSunny Srivastava * If the key does'nt exist then given interface and property map pair is newly
238fa5e4d32SSunny Srivastava * created. If the property present in propertymap already exist in the
239fa5e4d32SSunny Srivastava * InterfaceMap, then the new property value is ignored.
240fa5e4d32SSunny Srivastava *
241fa47e6c0SSouvik Roy * @param[in,out] io_map - Interface map.
242fa47e6c0SSouvik Roy * @param[in] i_interface - Interface to be processed.
243fa47e6c0SSouvik Roy * @param[in] i_propertyMap - new property map that needs to be emplaced.
244fa47e6c0SSouvik Roy *
245fa47e6c0SSouvik Roy * @return On success returns 0, otherwise returns -1.
246fa5e4d32SSunny Srivastava */
insertOrMerge(types::InterfaceMap & io_map,const std::string & i_interface,types::PropertyMap && i_propertyMap)247fa47e6c0SSouvik Roy inline int insertOrMerge(types::InterfaceMap& io_map,
248fa47e6c0SSouvik Roy const std::string& i_interface,
249fa47e6c0SSouvik Roy types::PropertyMap&& i_propertyMap) noexcept
250fa5e4d32SSunny Srivastava {
251fa47e6c0SSouvik Roy int l_rc{constants::FAILURE};
252fa5e4d32SSunny Srivastava try
253fa5e4d32SSunny Srivastava {
254fa47e6c0SSouvik Roy if (io_map.find(i_interface) != io_map.end())
255fa47e6c0SSouvik Roy {
256fa47e6c0SSouvik Roy auto& l_prop = io_map.at(i_interface);
257fa47e6c0SSouvik Roy std::for_each(i_propertyMap.begin(), i_propertyMap.end(),
258fa47e6c0SSouvik Roy [&l_prop](auto l_keyValue) {
259fa47e6c0SSouvik Roy l_prop[l_keyValue.first] = l_keyValue.second;
260fa5e4d32SSunny Srivastava });
261fa5e4d32SSunny Srivastava }
262fa47e6c0SSouvik Roy else
263fa47e6c0SSouvik Roy {
264fa47e6c0SSouvik Roy io_map.emplace(i_interface, i_propertyMap);
265fa47e6c0SSouvik Roy }
266fa47e6c0SSouvik Roy
267fa47e6c0SSouvik Roy l_rc = constants::SUCCESS;
268fa47e6c0SSouvik Roy }
269fa5e4d32SSunny Srivastava catch (const std::exception& l_ex)
270fa5e4d32SSunny Srivastava {
271fa5e4d32SSunny Srivastava // ToDo:: Log PEL
272fa5e4d32SSunny Srivastava logging::logMessage(
273fa47e6c0SSouvik Roy "Inserting properties into interface[" + i_interface +
274fa47e6c0SSouvik Roy "] map failed, reason: " + std::string(l_ex.what()));
275fa5e4d32SSunny Srivastava }
276fa47e6c0SSouvik Roy return l_rc;
277fa5e4d32SSunny Srivastava }
278fa5e4d32SSunny Srivastava
279fa5e4d32SSunny Srivastava /**
280fa5e4d32SSunny Srivastava * @brief API to expand unpanded location code.
281fa5e4d32SSunny Srivastava *
282fa5e4d32SSunny Srivastava * Note: The API handles all the exception internally, in case of any error
283fa5e4d32SSunny Srivastava * unexpanded location code will be returned as it is.
284fa5e4d32SSunny Srivastava *
285fa5e4d32SSunny Srivastava * @param[in] unexpandedLocationCode - Unexpanded location code.
286fa5e4d32SSunny Srivastava * @param[in] parsedVpdMap - Parsed VPD map.
287fa5e4d32SSunny Srivastava * @return Expanded location code. In case of any error, unexpanded is returned
288fa5e4d32SSunny Srivastava * as it is.
289fa5e4d32SSunny Srivastava */
getExpandedLocationCode(const std::string & unexpandedLocationCode,const types::VPDMapVariant & parsedVpdMap)29043fedabcSPatrick Williams inline std::string getExpandedLocationCode(
29143fedabcSPatrick Williams const std::string& unexpandedLocationCode,
292fa5e4d32SSunny Srivastava const types::VPDMapVariant& parsedVpdMap)
293fa5e4d32SSunny Srivastava {
294fa5e4d32SSunny Srivastava auto expanded{unexpandedLocationCode};
295fa5e4d32SSunny Srivastava
296fa5e4d32SSunny Srivastava try
297fa5e4d32SSunny Srivastava {
298fa5e4d32SSunny Srivastava // Expanded location code is formed by combining two keywords
299fa5e4d32SSunny Srivastava // depending on type in unexpanded one. Second one is always "SE".
300fa5e4d32SSunny Srivastava std::string kwd1, kwd2{constants::kwdSE};
301fa5e4d32SSunny Srivastava
302fa5e4d32SSunny Srivastava // interface to search for required keywords;
303fa5e4d32SSunny Srivastava std::string kwdInterface;
304fa5e4d32SSunny Srivastava
305fa5e4d32SSunny Srivastava // record which holds the required keywords.
306fa5e4d32SSunny Srivastava std::string recordName;
307fa5e4d32SSunny Srivastava
308fa5e4d32SSunny Srivastava auto pos = unexpandedLocationCode.find("fcs");
309fa5e4d32SSunny Srivastava if (pos != std::string::npos)
310fa5e4d32SSunny Srivastava {
311fa5e4d32SSunny Srivastava kwd1 = constants::kwdFC;
312fa5e4d32SSunny Srivastava kwdInterface = constants::vcenInf;
313fa5e4d32SSunny Srivastava recordName = constants::recVCEN;
314fa5e4d32SSunny Srivastava }
315fa5e4d32SSunny Srivastava else
316fa5e4d32SSunny Srivastava {
317fa5e4d32SSunny Srivastava pos = unexpandedLocationCode.find("mts");
318fa5e4d32SSunny Srivastava if (pos != std::string::npos)
319fa5e4d32SSunny Srivastava {
320fa5e4d32SSunny Srivastava kwd1 = constants::kwdTM;
321fa5e4d32SSunny Srivastava kwdInterface = constants::vsysInf;
322fa5e4d32SSunny Srivastava recordName = constants::recVSYS;
323fa5e4d32SSunny Srivastava }
324fa5e4d32SSunny Srivastava else
325fa5e4d32SSunny Srivastava {
326fa5e4d32SSunny Srivastava throw std::runtime_error(
327fa5e4d32SSunny Srivastava "Error detecting type of unexpanded location code.");
328fa5e4d32SSunny Srivastava }
329fa5e4d32SSunny Srivastava }
330fa5e4d32SSunny Srivastava
331fa5e4d32SSunny Srivastava std::string firstKwdValue, secondKwdValue;
332fa5e4d32SSunny Srivastava
333fa5e4d32SSunny Srivastava if (auto ipzVpdMap = std::get_if<types::IPZVpdMap>(&parsedVpdMap);
334fa5e4d32SSunny Srivastava ipzVpdMap && (*ipzVpdMap).find(recordName) != (*ipzVpdMap).end())
335fa5e4d32SSunny Srivastava {
336fa5e4d32SSunny Srivastava auto itrToVCEN = (*ipzVpdMap).find(recordName);
337a55fcca1SSouvik Roy firstKwdValue = getKwVal(itrToVCEN->second, kwd1);
338a55fcca1SSouvik Roy if (firstKwdValue.empty())
339a55fcca1SSouvik Roy {
340a55fcca1SSouvik Roy throw std::runtime_error(
341a55fcca1SSouvik Roy "Failed to get value for keyword [" + kwd1 + "]");
342a55fcca1SSouvik Roy }
343a55fcca1SSouvik Roy
344a55fcca1SSouvik Roy secondKwdValue = getKwVal(itrToVCEN->second, kwd2);
345a55fcca1SSouvik Roy if (secondKwdValue.empty())
346a55fcca1SSouvik Roy {
347a55fcca1SSouvik Roy throw std::runtime_error(
348a55fcca1SSouvik Roy "Failed to get value for keyword [" + kwd2 + "]");
349a55fcca1SSouvik Roy }
350fa5e4d32SSunny Srivastava }
351fa5e4d32SSunny Srivastava else
352fa5e4d32SSunny Srivastava {
353fa5e4d32SSunny Srivastava std::array<const char*, 1> interfaceList = {kwdInterface.c_str()};
354fa5e4d32SSunny Srivastava
355fa5e4d32SSunny Srivastava types::MapperGetObject mapperRetValue = dbusUtility::getObjectMap(
356fa5e4d32SSunny Srivastava std::string(constants::systemVpdInvPath), interfaceList);
357fa5e4d32SSunny Srivastava
358fa5e4d32SSunny Srivastava if (mapperRetValue.empty())
359fa5e4d32SSunny Srivastava {
360fa5e4d32SSunny Srivastava throw std::runtime_error("Mapper failed to get service");
361fa5e4d32SSunny Srivastava }
362fa5e4d32SSunny Srivastava
363fa5e4d32SSunny Srivastava const std::string& serviceName = std::get<0>(mapperRetValue.at(0));
364fa5e4d32SSunny Srivastava
365fa5e4d32SSunny Srivastava auto retVal = dbusUtility::readDbusProperty(
366fa5e4d32SSunny Srivastava serviceName, std::string(constants::systemVpdInvPath),
367fa5e4d32SSunny Srivastava kwdInterface, kwd1);
368fa5e4d32SSunny Srivastava
369fa5e4d32SSunny Srivastava if (auto kwdVal = std::get_if<types::BinaryVector>(&retVal))
370fa5e4d32SSunny Srivastava {
371fa5e4d32SSunny Srivastava firstKwdValue.assign(
372fa5e4d32SSunny Srivastava reinterpret_cast<const char*>(kwdVal->data()),
373fa5e4d32SSunny Srivastava kwdVal->size());
374fa5e4d32SSunny Srivastava }
375fa5e4d32SSunny Srivastava else
376fa5e4d32SSunny Srivastava {
377fa5e4d32SSunny Srivastava throw std::runtime_error(
378fa5e4d32SSunny Srivastava "Failed to read value of " + kwd1 + " from Bus");
379fa5e4d32SSunny Srivastava }
380fa5e4d32SSunny Srivastava
381fa5e4d32SSunny Srivastava retVal = dbusUtility::readDbusProperty(
382fa5e4d32SSunny Srivastava serviceName, std::string(constants::systemVpdInvPath),
383fa5e4d32SSunny Srivastava kwdInterface, kwd2);
384fa5e4d32SSunny Srivastava
385fa5e4d32SSunny Srivastava if (auto kwdVal = std::get_if<types::BinaryVector>(&retVal))
386fa5e4d32SSunny Srivastava {
387fa5e4d32SSunny Srivastava secondKwdValue.assign(
388fa5e4d32SSunny Srivastava reinterpret_cast<const char*>(kwdVal->data()),
389fa5e4d32SSunny Srivastava kwdVal->size());
390fa5e4d32SSunny Srivastava }
391fa5e4d32SSunny Srivastava else
392fa5e4d32SSunny Srivastava {
393fa5e4d32SSunny Srivastava throw std::runtime_error(
394fa5e4d32SSunny Srivastava "Failed to read value of " + kwd2 + " from Bus");
395fa5e4d32SSunny Srivastava }
396fa5e4d32SSunny Srivastava }
397fa5e4d32SSunny Srivastava
398fa5e4d32SSunny Srivastava if (unexpandedLocationCode.find("fcs") != std::string::npos)
399fa5e4d32SSunny Srivastava {
400fa5e4d32SSunny Srivastava // TODO: See if ND0 can be placed in the JSON
401fa5e4d32SSunny Srivastava expanded.replace(
402fa5e4d32SSunny Srivastava pos, 3, firstKwdValue.substr(0, 4) + ".ND0." + secondKwdValue);
403fa5e4d32SSunny Srivastava }
404fa5e4d32SSunny Srivastava else
405fa5e4d32SSunny Srivastava {
406fa5e4d32SSunny Srivastava replace(firstKwdValue.begin(), firstKwdValue.end(), '-', '.');
407fa5e4d32SSunny Srivastava expanded.replace(pos, 3, firstKwdValue + "." + secondKwdValue);
408fa5e4d32SSunny Srivastava }
409fa5e4d32SSunny Srivastava }
410fa5e4d32SSunny Srivastava catch (const std::exception& ex)
411fa5e4d32SSunny Srivastava {
412fa5e4d32SSunny Srivastava logging::logMessage("Failed to expand location code with exception: " +
413fa5e4d32SSunny Srivastava std::string(ex.what()));
414fa5e4d32SSunny Srivastava }
415fa5e4d32SSunny Srivastava
416fa5e4d32SSunny Srivastava return expanded;
417fa5e4d32SSunny Srivastava }
418fa5e4d32SSunny Srivastava
419fa5e4d32SSunny Srivastava /**
420fa5e4d32SSunny Srivastava * @brief An API to get VPD in a vector.
421fa5e4d32SSunny Srivastava *
422fa5e4d32SSunny Srivastava * The vector is required by the respective parser to fill the VPD map.
423fa5e4d32SSunny Srivastava * Note: API throws exception in case of failure. Caller needs to handle.
424fa5e4d32SSunny Srivastava *
425fa5e4d32SSunny Srivastava * @param[in] vpdFilePath - EEPROM path of the FRU.
426fa5e4d32SSunny Srivastava * @param[out] vpdVector - VPD in vector form.
427fa5e4d32SSunny Srivastava * @param[in] vpdStartOffset - Offset of VPD data in EEPROM.
428fa5e4d32SSunny Srivastava */
getVpdDataInVector(const std::string & vpdFilePath,types::BinaryVector & vpdVector,size_t & vpdStartOffset)429fa5e4d32SSunny Srivastava inline void getVpdDataInVector(const std::string& vpdFilePath,
430fa5e4d32SSunny Srivastava types::BinaryVector& vpdVector,
431fa5e4d32SSunny Srivastava size_t& vpdStartOffset)
432fa5e4d32SSunny Srivastava {
433fa5e4d32SSunny Srivastava try
434fa5e4d32SSunny Srivastava {
435fa5e4d32SSunny Srivastava std::fstream vpdFileStream;
436fa5e4d32SSunny Srivastava vpdFileStream.exceptions(
437fa5e4d32SSunny Srivastava std::ifstream::badbit | std::ifstream::failbit);
438fa5e4d32SSunny Srivastava vpdFileStream.open(vpdFilePath, std::ios::in | std::ios::binary);
439fa5e4d32SSunny Srivastava auto vpdSizeToRead = std::min(std::filesystem::file_size(vpdFilePath),
440fa5e4d32SSunny Srivastava static_cast<uintmax_t>(65504));
441fa5e4d32SSunny Srivastava vpdVector.resize(vpdSizeToRead);
442fa5e4d32SSunny Srivastava
443fa5e4d32SSunny Srivastava vpdFileStream.seekg(vpdStartOffset, std::ios_base::beg);
444fa5e4d32SSunny Srivastava vpdFileStream.read(reinterpret_cast<char*>(&vpdVector[0]),
445fa5e4d32SSunny Srivastava vpdSizeToRead);
446fa5e4d32SSunny Srivastava
447fa5e4d32SSunny Srivastava vpdVector.resize(vpdFileStream.gcount());
448fa5e4d32SSunny Srivastava vpdFileStream.clear(std::ios_base::eofbit);
449fa5e4d32SSunny Srivastava }
450fa5e4d32SSunny Srivastava catch (const std::ifstream::failure& fail)
451fa5e4d32SSunny Srivastava {
452fa5e4d32SSunny Srivastava std::cerr << "Exception in file handling [" << vpdFilePath
453fa5e4d32SSunny Srivastava << "] error : " << fail.what();
454fa5e4d32SSunny Srivastava throw;
455fa5e4d32SSunny Srivastava }
456fa5e4d32SSunny Srivastava }
457fa5e4d32SSunny Srivastava
458fa5e4d32SSunny Srivastava /**
459fa5e4d32SSunny Srivastava * @brief An API to get D-bus representation of given VPD keyword.
460fa5e4d32SSunny Srivastava *
461fa5e4d32SSunny Srivastava * @param[in] i_keywordName - VPD keyword name.
462fa5e4d32SSunny Srivastava *
463fa5e4d32SSunny Srivastava * @return D-bus representation of given keyword.
464fa5e4d32SSunny Srivastava */
getDbusPropNameForGivenKw(const std::string & i_keywordName)465fa5e4d32SSunny Srivastava inline std::string getDbusPropNameForGivenKw(const std::string& i_keywordName)
466fa5e4d32SSunny Srivastava {
467fa5e4d32SSunny Srivastava // Check for "#" prefixed VPD keyword.
468fa5e4d32SSunny Srivastava if ((i_keywordName.size() == vpd::constants::TWO_BYTES) &&
469fa5e4d32SSunny Srivastava (i_keywordName.at(0) == constants::POUND_KW))
470fa5e4d32SSunny Srivastava {
471fa5e4d32SSunny Srivastava // D-bus doesn't support "#". Replace "#" with "PD_" for those "#"
472fa5e4d32SSunny Srivastava // prefixed keywords.
473fa5e4d32SSunny Srivastava return (std::string(constants::POUND_KW_PREFIX) +
474fa5e4d32SSunny Srivastava i_keywordName.substr(1));
475fa5e4d32SSunny Srivastava }
476fa5e4d32SSunny Srivastava
477fa5e4d32SSunny Srivastava // Return the keyword name back, if D-bus representation is same as the VPD
478fa5e4d32SSunny Srivastava // keyword name.
479fa5e4d32SSunny Srivastava return i_keywordName;
480fa5e4d32SSunny Srivastava }
481fa5e4d32SSunny Srivastava
482fa5e4d32SSunny Srivastava /**
483fa5e4d32SSunny Srivastava * @brief API to find CCIN in parsed VPD map.
484fa5e4d32SSunny Srivastava *
485fa5e4d32SSunny Srivastava * Few FRUs need some special handling. To identify those FRUs CCIN are used.
486fa5e4d32SSunny Srivastava * The API will check from parsed VPD map if the FRU is the one with desired
487fa5e4d32SSunny Srivastava * CCIN.
488fa5e4d32SSunny Srivastava *
489fa5e4d32SSunny Srivastava * @param[in] i_JsonObject - Any JSON which contains CCIN tag to match.
490fa5e4d32SSunny Srivastava * @param[in] i_parsedVpdMap - Parsed VPD map.
491815c6029SSouvik Roy *
492fa5e4d32SSunny Srivastava * @return True if found, false otherwise.
493fa5e4d32SSunny Srivastava */
findCcinInVpd(const nlohmann::json & i_JsonObject,const types::VPDMapVariant & i_parsedVpdMap)494fa5e4d32SSunny Srivastava inline bool findCcinInVpd(const nlohmann::json& i_JsonObject,
495815c6029SSouvik Roy const types::VPDMapVariant& i_parsedVpdMap) noexcept
496815c6029SSouvik Roy {
497815c6029SSouvik Roy bool l_rc{false};
498815c6029SSouvik Roy try
499fa5e4d32SSunny Srivastava {
500fa5e4d32SSunny Srivastava if (i_JsonObject.empty())
501fa5e4d32SSunny Srivastava {
502fa5e4d32SSunny Srivastava throw std::runtime_error("Json object is empty. Can't find CCIN");
503fa5e4d32SSunny Srivastava }
504fa5e4d32SSunny Srivastava
505fa5e4d32SSunny Srivastava if (auto l_ipzVPDMap = std::get_if<types::IPZVpdMap>(&i_parsedVpdMap))
506fa5e4d32SSunny Srivastava {
507fa5e4d32SSunny Srivastava auto l_itrToRec = (*l_ipzVPDMap).find("VINI");
508fa5e4d32SSunny Srivastava if (l_itrToRec == (*l_ipzVPDMap).end())
509fa5e4d32SSunny Srivastava {
510fa5e4d32SSunny Srivastava throw DataException(
511fa5e4d32SSunny Srivastava "VINI record not found in parsed VPD. Can't find CCIN");
512fa5e4d32SSunny Srivastava }
513fa5e4d32SSunny Srivastava
514a55fcca1SSouvik Roy std::string l_ccinFromVpd{
515a55fcca1SSouvik Roy vpdSpecificUtility::getKwVal(l_itrToRec->second, "CC")};
516fa5e4d32SSunny Srivastava if (l_ccinFromVpd.empty())
517fa5e4d32SSunny Srivastava {
518815c6029SSouvik Roy throw DataException(
519815c6029SSouvik Roy "Empty CCIN value in VPD map. Can't find CCIN");
520fa5e4d32SSunny Srivastava }
521fa5e4d32SSunny Srivastava
522fa5e4d32SSunny Srivastava transform(l_ccinFromVpd.begin(), l_ccinFromVpd.end(),
523fa5e4d32SSunny Srivastava l_ccinFromVpd.begin(), ::toupper);
524fa5e4d32SSunny Srivastava
525fa5e4d32SSunny Srivastava for (std::string l_ccinValue : i_JsonObject["ccin"])
526fa5e4d32SSunny Srivastava {
527fa5e4d32SSunny Srivastava transform(l_ccinValue.begin(), l_ccinValue.end(),
528fa5e4d32SSunny Srivastava l_ccinValue.begin(), ::toupper);
529fa5e4d32SSunny Srivastava
530fa5e4d32SSunny Srivastava if (l_ccinValue.compare(l_ccinFromVpd) ==
531fa5e4d32SSunny Srivastava constants::STR_CMP_SUCCESS)
532fa5e4d32SSunny Srivastava {
533fa5e4d32SSunny Srivastava // CCIN found
534815c6029SSouvik Roy l_rc = true;
535fa5e4d32SSunny Srivastava }
536fa5e4d32SSunny Srivastava }
537fa5e4d32SSunny Srivastava
538815c6029SSouvik Roy if (!l_rc)
539815c6029SSouvik Roy {
540fa5e4d32SSunny Srivastava logging::logMessage("No match found for CCIN");
541815c6029SSouvik Roy }
542815c6029SSouvik Roy }
543815c6029SSouvik Roy else
544815c6029SSouvik Roy {
545815c6029SSouvik Roy logging::logMessage("VPD type not supported. Can't find CCIN");
546815c6029SSouvik Roy }
547815c6029SSouvik Roy }
548815c6029SSouvik Roy catch (const std::exception& l_ex)
549815c6029SSouvik Roy {
550815c6029SSouvik Roy const std::string l_errMsg{
551815c6029SSouvik Roy "Failed to find CCIN in VPD. Error : " + std::string(l_ex.what())};
552815c6029SSouvik Roy
553815c6029SSouvik Roy if (typeid(l_ex) == std::type_index(typeid(DataException)))
554815c6029SSouvik Roy {
555815c6029SSouvik Roy EventLogger::createSyncPel(
556815c6029SSouvik Roy types::ErrorType::InvalidVpdMessage,
557815c6029SSouvik Roy types::SeverityType::Informational, __FILE__, __FUNCTION__, 0,
558815c6029SSouvik Roy l_errMsg, std::nullopt, std::nullopt, std::nullopt,
559815c6029SSouvik Roy std::nullopt);
560fa5e4d32SSunny Srivastava }
561fa5e4d32SSunny Srivastava
562815c6029SSouvik Roy logging::logMessage(l_errMsg);
563815c6029SSouvik Roy }
564815c6029SSouvik Roy return l_rc;
565fa5e4d32SSunny Srivastava }
566fa5e4d32SSunny Srivastava
567fa5e4d32SSunny Srivastava /**
568fa5e4d32SSunny Srivastava * @brief API to reset data of a FRU populated under PIM.
569fa5e4d32SSunny Srivastava *
570fa5e4d32SSunny Srivastava * This API resets the data for particular interfaces of a FRU under PIM.
571fa5e4d32SSunny Srivastava *
572fa5e4d32SSunny Srivastava * @param[in] i_objectPath - DBus object path of the FRU.
573fa5e4d32SSunny Srivastava * @param[in] io_interfaceMap - Interface and its properties map.
574fa5e4d32SSunny Srivastava */
resetDataUnderPIM(const std::string & i_objectPath,types::InterfaceMap & io_interfaceMap)575fa5e4d32SSunny Srivastava inline void resetDataUnderPIM(const std::string& i_objectPath,
576fa5e4d32SSunny Srivastava types::InterfaceMap& io_interfaceMap)
577fa5e4d32SSunny Srivastava {
578fa5e4d32SSunny Srivastava try
579fa5e4d32SSunny Srivastava {
580fa5e4d32SSunny Srivastava std::array<const char*, 0> l_interfaces;
581fa5e4d32SSunny Srivastava const types::MapperGetObject& l_getObjectMap =
582fa5e4d32SSunny Srivastava dbusUtility::getObjectMap(i_objectPath, l_interfaces);
583fa5e4d32SSunny Srivastava
584fa5e4d32SSunny Srivastava const std::vector<std::string>& l_vpdRelatedInterfaces{
585fa5e4d32SSunny Srivastava constants::operationalStatusInf, constants::inventoryItemInf,
586fa5e4d32SSunny Srivastava constants::assetInf};
587fa5e4d32SSunny Srivastava
588fa5e4d32SSunny Srivastava for (const auto& [l_service, l_interfaceList] : l_getObjectMap)
589fa5e4d32SSunny Srivastava {
590fa5e4d32SSunny Srivastava if (l_service.compare(constants::pimServiceName) !=
591fa5e4d32SSunny Srivastava constants::STR_CMP_SUCCESS)
592fa5e4d32SSunny Srivastava {
593fa5e4d32SSunny Srivastava continue;
594fa5e4d32SSunny Srivastava }
595fa5e4d32SSunny Srivastava
596fa5e4d32SSunny Srivastava for (const auto& l_interface : l_interfaceList)
597fa5e4d32SSunny Srivastava {
598fa5e4d32SSunny Srivastava if ((l_interface.find(constants::ipzVpdInf) !=
599fa5e4d32SSunny Srivastava std::string::npos) ||
600fa5e4d32SSunny Srivastava ((std::find(l_vpdRelatedInterfaces.begin(),
601fa5e4d32SSunny Srivastava l_vpdRelatedInterfaces.end(), l_interface)) !=
602fa5e4d32SSunny Srivastava l_vpdRelatedInterfaces.end()))
603fa5e4d32SSunny Srivastava {
604fa5e4d32SSunny Srivastava const types::PropertyMap& l_propertyValueMap =
605fa5e4d32SSunny Srivastava dbusUtility::getPropertyMap(l_service, i_objectPath,
606fa5e4d32SSunny Srivastava l_interface);
607fa5e4d32SSunny Srivastava
608fa5e4d32SSunny Srivastava types::PropertyMap l_propertyMap;
609fa5e4d32SSunny Srivastava
610fa5e4d32SSunny Srivastava for (const auto& l_aProperty : l_propertyValueMap)
611fa5e4d32SSunny Srivastava {
612fa5e4d32SSunny Srivastava const std::string& l_propertyName = l_aProperty.first;
613fa5e4d32SSunny Srivastava const auto& l_propertyValue = l_aProperty.second;
614fa5e4d32SSunny Srivastava
615fa5e4d32SSunny Srivastava if (std::holds_alternative<types::BinaryVector>(
616fa5e4d32SSunny Srivastava l_propertyValue))
617fa5e4d32SSunny Srivastava {
618fa5e4d32SSunny Srivastava l_propertyMap.emplace(l_propertyName,
619fa5e4d32SSunny Srivastava types::BinaryVector{});
620fa5e4d32SSunny Srivastava }
621fa5e4d32SSunny Srivastava else if (std::holds_alternative<std::string>(
622fa5e4d32SSunny Srivastava l_propertyValue))
623fa5e4d32SSunny Srivastava {
624fa5e4d32SSunny Srivastava l_propertyMap.emplace(l_propertyName,
625fa5e4d32SSunny Srivastava std::string{});
626fa5e4d32SSunny Srivastava }
627fa5e4d32SSunny Srivastava else if (std::holds_alternative<bool>(l_propertyValue))
628fa5e4d32SSunny Srivastava {
629fa5e4d32SSunny Srivastava // ToDo -- Update the functional status property
630fa5e4d32SSunny Srivastava // to true.
631fa5e4d32SSunny Srivastava if (l_propertyName.compare("Present") ==
632fa5e4d32SSunny Srivastava constants::STR_CMP_SUCCESS)
633fa5e4d32SSunny Srivastava {
634fa5e4d32SSunny Srivastava l_propertyMap.emplace(l_propertyName, false);
635fa5e4d32SSunny Srivastava }
636fa5e4d32SSunny Srivastava }
637fa5e4d32SSunny Srivastava }
638fa5e4d32SSunny Srivastava io_interfaceMap.emplace(l_interface,
639fa5e4d32SSunny Srivastava std::move(l_propertyMap));
640fa5e4d32SSunny Srivastava }
641fa5e4d32SSunny Srivastava }
642fa5e4d32SSunny Srivastava }
643fa5e4d32SSunny Srivastava }
644fa5e4d32SSunny Srivastava catch (const std::exception& l_ex)
645fa5e4d32SSunny Srivastava {
646fa5e4d32SSunny Srivastava logging::logMessage("Failed to remove VPD for FRU: " + i_objectPath +
647fa5e4d32SSunny Srivastava " with error: " + std::string(l_ex.what()));
648fa5e4d32SSunny Srivastava }
649fa5e4d32SSunny Srivastava }
65078c91073SSunny Srivastava
65178c91073SSunny Srivastava /**
65278c91073SSunny Srivastava * @brief API to detect pass1 planar type.
65378c91073SSunny Srivastava *
65478c91073SSunny Srivastava * Based on HW version and IM keyword, This API detects is it is a pass1 planar
65578c91073SSunny Srivastava * or not.
65678c91073SSunny Srivastava *
65778c91073SSunny Srivastava * @return True if pass 1 planar, false otherwise.
65878c91073SSunny Srivastava */
isPass1Planar()659094a7352SSouvik Roy inline bool isPass1Planar() noexcept
660094a7352SSouvik Roy {
661094a7352SSouvik Roy bool l_rc{false};
662094a7352SSouvik Roy try
66378c91073SSunny Srivastava {
66478c91073SSunny Srivastava auto l_retVal = dbusUtility::readDbusProperty(
66578c91073SSunny Srivastava constants::pimServiceName, constants::systemVpdInvPath,
66678c91073SSunny Srivastava constants::viniInf, constants::kwdHW);
66778c91073SSunny Srivastava
66878c91073SSunny Srivastava auto l_hwVer = std::get_if<types::BinaryVector>(&l_retVal);
66978c91073SSunny Srivastava
67078c91073SSunny Srivastava l_retVal = dbusUtility::readDbusProperty(
671094a7352SSouvik Roy constants::pimServiceName, constants::systemInvPath,
672094a7352SSouvik Roy constants::vsbpInf, constants::kwdIM);
67378c91073SSunny Srivastava
67478c91073SSunny Srivastava auto l_imValue = std::get_if<types::BinaryVector>(&l_retVal);
67578c91073SSunny Srivastava
67678c91073SSunny Srivastava if (l_hwVer && l_imValue)
67778c91073SSunny Srivastava {
678094a7352SSouvik Roy if (l_hwVer->size() != constants::VALUE_2)
679094a7352SSouvik Roy {
680094a7352SSouvik Roy throw std::runtime_error("Invalid HW keyword length.");
681094a7352SSouvik Roy }
68278c91073SSunny Srivastava
683094a7352SSouvik Roy if (l_imValue->size() != constants::VALUE_4)
684094a7352SSouvik Roy {
685094a7352SSouvik Roy throw std::runtime_error("Invalid IM keyword length.");
686094a7352SSouvik Roy }
687094a7352SSouvik Roy
688094a7352SSouvik Roy const types::BinaryVector l_everest{80, 00, 48, 00};
689094a7352SSouvik Roy const types::BinaryVector l_fuji{96, 00, 32, 00};
690094a7352SSouvik Roy
691094a7352SSouvik Roy if (((*l_imValue) == l_everest) || ((*l_imValue) == l_fuji))
69278c91073SSunny Srivastava {
69378c91073SSunny Srivastava if ((*l_hwVer).at(1) < constants::VALUE_21)
69478c91073SSunny Srivastava {
695094a7352SSouvik Roy l_rc = true;
69678c91073SSunny Srivastava }
69778c91073SSunny Srivastava }
69878c91073SSunny Srivastava else if ((*l_hwVer).at(1) < constants::VALUE_2)
69978c91073SSunny Srivastava {
700094a7352SSouvik Roy l_rc = true;
70178c91073SSunny Srivastava }
70278c91073SSunny Srivastava }
703094a7352SSouvik Roy }
704094a7352SSouvik Roy catch (const std::exception& l_ex)
705094a7352SSouvik Roy {
706094a7352SSouvik Roy logging::logMessage("Failed to check for pass 1 planar. Error: " +
707094a7352SSouvik Roy std::string(l_ex.what()));
708094a7352SSouvik Roy }
70978c91073SSunny Srivastava
710094a7352SSouvik Roy return l_rc;
71178c91073SSunny Srivastava }
712c6ef42d6SSunny Srivastava
713c6ef42d6SSunny Srivastava /**
714c6ef42d6SSunny Srivastava * @brief API to detect if system configuration is that of PowerVS system.
715c6ef42d6SSunny Srivastava *
716c6ef42d6SSunny Srivastava * @param[in] i_imValue - IM value of the system.
717c6ef42d6SSunny Srivastava * @return true if it is PowerVS configuration, false otherwise.
718c6ef42d6SSunny Srivastava */
isPowerVsConfiguration(const types::BinaryVector & i_imValue)719c6ef42d6SSunny Srivastava inline bool isPowerVsConfiguration(const types::BinaryVector& i_imValue)
720c6ef42d6SSunny Srivastava {
721c6ef42d6SSunny Srivastava if (i_imValue.empty() || i_imValue.size() != constants::VALUE_4)
722c6ef42d6SSunny Srivastava {
723c6ef42d6SSunny Srivastava return false;
724c6ef42d6SSunny Srivastava }
725c6ef42d6SSunny Srivastava
726c6ef42d6SSunny Srivastava // Should be a 0x5000XX series system.
727c6ef42d6SSunny Srivastava if (i_imValue.at(0) == constants::HEX_VALUE_50 &&
728c6ef42d6SSunny Srivastava i_imValue.at(1) == constants::HEX_VALUE_00)
729c6ef42d6SSunny Srivastava {
730c6ef42d6SSunny Srivastava std::string l_imagePrefix = dbusUtility::getImagePrefix();
731c6ef42d6SSunny Srivastava
732c6ef42d6SSunny Srivastava // Check image for 0x500030XX series.
733c6ef42d6SSunny Srivastava if ((i_imValue.at(2) == constants::HEX_VALUE_30) &&
734c6ef42d6SSunny Srivastava ((l_imagePrefix == constants::powerVsImagePrefix_MY) ||
735c6ef42d6SSunny Srivastava (l_imagePrefix == constants::powerVsImagePrefix_NY)))
736c6ef42d6SSunny Srivastava {
737c6ef42d6SSunny Srivastava logging::logMessage("PowerVS configuration");
738c6ef42d6SSunny Srivastava return true;
739c6ef42d6SSunny Srivastava }
740c6ef42d6SSunny Srivastava
741c6ef42d6SSunny Srivastava // Check image for 0X500010XX series.
742c6ef42d6SSunny Srivastava if ((i_imValue.at(2) == constants::HEX_VALUE_10) &&
743c6ef42d6SSunny Srivastava ((l_imagePrefix == constants::powerVsImagePrefix_MZ) ||
744c6ef42d6SSunny Srivastava (l_imagePrefix == constants::powerVsImagePrefix_NZ)))
745c6ef42d6SSunny Srivastava {
746c6ef42d6SSunny Srivastava logging::logMessage("PowerVS configuration");
747c6ef42d6SSunny Srivastava return true;
748c6ef42d6SSunny Srivastava }
749c6ef42d6SSunny Srivastava }
750c6ef42d6SSunny Srivastava return false;
751c6ef42d6SSunny Srivastava }
752f1dda767SSunny Srivastava
753f1dda767SSunny Srivastava /**
754f1dda767SSunny Srivastava * @brief API to get CCIN for a given FRU from DBus.
755f1dda767SSunny Srivastava *
756f1dda767SSunny Srivastava * The API reads the CCIN for a FRU based on its inventory path.
757f1dda767SSunny Srivastava *
758f1dda767SSunny Srivastava * @param[in] i_invObjPath - Inventory path of the FRU.
759f1dda767SSunny Srivastava * @return CCIN of the FRU on success, empty string otherwise.
760f1dda767SSunny Srivastava */
getCcinFromDbus(const std::string & i_invObjPath)761f1dda767SSunny Srivastava inline std::string getCcinFromDbus(const std::string& i_invObjPath)
762f1dda767SSunny Srivastava {
763f1dda767SSunny Srivastava try
764f1dda767SSunny Srivastava {
765f1dda767SSunny Srivastava if (i_invObjPath.empty())
766f1dda767SSunny Srivastava {
767f1dda767SSunny Srivastava throw std::runtime_error("Empty EEPROM path, can't read CCIN");
768f1dda767SSunny Srivastava }
769f1dda767SSunny Srivastava
770f1dda767SSunny Srivastava const auto& l_retValue = dbusUtility::readDbusProperty(
771f1dda767SSunny Srivastava constants::pimServiceName, i_invObjPath, constants::viniInf,
772f1dda767SSunny Srivastava constants::kwdCCIN);
773f1dda767SSunny Srivastava
774f1dda767SSunny Srivastava auto l_ptrCcin = std::get_if<types::BinaryVector>(&l_retValue);
775f1dda767SSunny Srivastava if (!l_ptrCcin || (*l_ptrCcin).size() != constants::VALUE_4)
776f1dda767SSunny Srivastava {
777f1dda767SSunny Srivastava throw DbusException("Invalid CCIN read from Dbus");
778f1dda767SSunny Srivastava }
779f1dda767SSunny Srivastava
780f1dda767SSunny Srivastava return std::string((*l_ptrCcin).begin(), (*l_ptrCcin).end());
781f1dda767SSunny Srivastava }
782f1dda767SSunny Srivastava catch (const std::exception& l_ex)
783f1dda767SSunny Srivastava {
784f1dda767SSunny Srivastava logging::logMessage(l_ex.what());
785f1dda767SSunny Srivastava return std::string{};
786f1dda767SSunny Srivastava }
787f1dda767SSunny Srivastava }
788ecfaa215SSunny Srivastava
789ecfaa215SSunny Srivastava /**
790ecfaa215SSunny Srivastava * @brief API to check if the current running image is a powerVS image.
791ecfaa215SSunny Srivastava *
792ecfaa215SSunny Srivastava * @return true if it is PowerVS image, false otherwise.
793ecfaa215SSunny Srivastava */
isPowerVsImage()794ecfaa215SSunny Srivastava inline bool isPowerVsImage()
795ecfaa215SSunny Srivastava {
796ecfaa215SSunny Srivastava std::string l_imagePrefix = dbusUtility::getImagePrefix();
797ecfaa215SSunny Srivastava
798ecfaa215SSunny Srivastava if ((l_imagePrefix == constants::powerVsImagePrefix_MY) ||
799ecfaa215SSunny Srivastava (l_imagePrefix == constants::powerVsImagePrefix_NY) ||
800ecfaa215SSunny Srivastava (l_imagePrefix == constants::powerVsImagePrefix_MZ) ||
801ecfaa215SSunny Srivastava (l_imagePrefix == constants::powerVsImagePrefix_NZ))
802ecfaa215SSunny Srivastava {
803ecfaa215SSunny Srivastava return true;
804ecfaa215SSunny Srivastava }
805ecfaa215SSunny Srivastava return false;
806ecfaa215SSunny Srivastava }
807fa5e4d32SSunny Srivastava } // namespace vpdSpecificUtility
808fa5e4d32SSunny Srivastava } // namespace vpd
809