xref: /openbmc/openpower-vpd-parser/vpd-manager/include/utility/vpd_specific_utility.hpp (revision 0f370434621997eea8ac37d69834e9ada810068d)
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