blob: 6b2f685659058d6287fba5c0368c7ac9942ee7c4 [file] [log] [blame]
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -05001#pragma once
2
3#include "config.h"
4
5#include "constants.hpp"
6#include "exceptions.hpp"
7#include "logger.hpp"
8#include "types.hpp"
9
10#include <nlohmann/json.hpp>
11#include <utility/common_utility.hpp>
12#include <utility/dbus_utility.hpp>
13
14#include <filesystem>
15#include <fstream>
16#include <regex>
17
18namespace vpd
19{
20namespace vpdSpecificUtility
21{
22/**
23 * @brief API to generate file name for bad VPD.
24 *
25 * For i2c eeproms - the pattern of the vpd-name will be
26 * i2c-<bus-number>-<eeprom-address>.
27 * For spi eeproms - the pattern of the vpd-name will be spi-<spi-number>.
28 *
Souvik Roy8fc12522025-02-19 01:28:38 -060029 * @param[in] i_vpdFilePath - file path of the vpd.
30 *
31 * @return On success, returns generated file name, otherwise returns empty
32 * string.
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -050033 */
Souvik Roy8fc12522025-02-19 01:28:38 -060034inline std::string generateBadVPDFileName(
35 const std::string& i_vpdFilePath) noexcept
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -050036{
Souvik Roy8fc12522025-02-19 01:28:38 -060037 std::string l_badVpdFileName{BAD_VPD_DIR};
38 try
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -050039 {
Souvik Roy8fc12522025-02-19 01:28:38 -060040 if (i_vpdFilePath.find("i2c") != std::string::npos)
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -050041 {
Souvik Roy8fc12522025-02-19 01:28:38 -060042 l_badVpdFileName += "i2c-";
43 std::regex l_i2cPattern("(at24/)([0-9]+-[0-9]+)\\/");
44 std::smatch l_match;
45 if (std::regex_search(i_vpdFilePath, l_match, l_i2cPattern))
46 {
47 l_badVpdFileName += l_match.str(2);
48 }
49 }
50 else if (i_vpdFilePath.find("spi") != std::string::npos)
51 {
52 std::regex l_spiPattern("((spi)[0-9]+)(.0)");
53 std::smatch l_match;
54 if (std::regex_search(i_vpdFilePath, l_match, l_spiPattern))
55 {
56 l_badVpdFileName += l_match.str(1);
57 }
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -050058 }
59 }
Souvik Roy8fc12522025-02-19 01:28:38 -060060 catch (const std::exception& l_ex)
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -050061 {
Souvik Roy8fc12522025-02-19 01:28:38 -060062 l_badVpdFileName.clear();
63 logging::logMessage("Failed to generate bad VPD file name for [" +
64 i_vpdFilePath + "]. Error: " + l_ex.what());
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -050065 }
Souvik Roy8fc12522025-02-19 01:28:38 -060066 return l_badVpdFileName;
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -050067}
68
69/**
70 * @brief API which dumps the broken/bad vpd in a directory.
71 * When the vpd is bad, this API places the bad vpd file inside
72 * "/tmp/bad-vpd" in BMC, in order to collect bad VPD data as a part of user
73 * initiated BMC dump.
74 *
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -050075 *
Souvik Roy8fc12522025-02-19 01:28:38 -060076 * @param[in] i_vpdFilePath - vpd file path
77 * @param[in] i_vpdVector - vpd vector
78 *
79 * @return On success returns 0, otherwise returns -1.
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -050080 */
Souvik Roy8fc12522025-02-19 01:28:38 -060081inline int dumpBadVpd(const std::string& i_vpdFilePath,
82 const types::BinaryVector& i_vpdVector) noexcept
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -050083{
Souvik Roy8fc12522025-02-19 01:28:38 -060084 int l_rc{constants::FAILURE};
85 try
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -050086 {
Souvik Roy8fc12522025-02-19 01:28:38 -060087 std::filesystem::create_directory(BAD_VPD_DIR);
88 auto l_badVpdPath = generateBadVPDFileName(i_vpdFilePath);
89
90 if (l_badVpdPath.empty())
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -050091 {
Souvik Roy8fc12522025-02-19 01:28:38 -060092 throw std::runtime_error("Failed to generate bad VPD file name");
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -050093 }
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -050094
Souvik Roy8fc12522025-02-19 01:28:38 -060095 if (std::filesystem::exists(l_badVpdPath))
96 {
97 std::error_code l_ec;
98 std::filesystem::remove(l_badVpdPath, l_ec);
99 if (l_ec) // error code
100 {
101 const std::string l_errorMsg{
102 "Error removing the existing broken vpd in " +
103 l_badVpdPath +
104 ". Error code : " + std::to_string(l_ec.value()) +
105 ". Error message : " + l_ec.message()};
106
107 throw std::runtime_error(l_errorMsg);
108 }
109 }
110
111 std::ofstream l_badVpdFileStream(l_badVpdPath, std::ofstream::binary);
112 if (!l_badVpdFileStream.is_open())
113 {
114 throw std::runtime_error(
115 "Failed to open bad vpd file path in /tmp/bad-vpd. "
116 "Unable to dump the broken/bad vpd file.");
117 }
118
119 l_badVpdFileStream.write(
120 reinterpret_cast<const char*>(i_vpdVector.data()),
121 i_vpdVector.size());
122
123 l_rc = constants::SUCCESS;
124 }
125 catch (const std::exception& l_ex)
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500126 {
Souvik Roy8fc12522025-02-19 01:28:38 -0600127 logging::logMessage("Failed to dump bad VPD for [" + i_vpdFilePath +
128 "]. Error: " + l_ex.what());
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500129 }
Souvik Roy8fc12522025-02-19 01:28:38 -0600130 return l_rc;
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500131}
132
133/**
134 * @brief An API to read value of a keyword.
135 *
136 * Note: Throws exception. Caller needs to handle.
137 *
138 * @param[in] kwdValueMap - A map having Kwd value pair.
139 * @param[in] kwd - keyword name.
140 * @param[out] kwdValue - Value of the keyword read from map.
141 */
142inline void getKwVal(const types::IPZKwdValueMap& kwdValueMap,
143 const std::string& kwd, std::string& kwdValue)
144{
145 if (kwd.empty())
146 {
147 logging::logMessage("Invalid parameters");
148 throw std::runtime_error("Invalid parameters");
149 }
150
151 auto itrToKwd = kwdValueMap.find(kwd);
152 if (itrToKwd != kwdValueMap.end())
153 {
154 kwdValue = itrToKwd->second;
155 return;
156 }
157
158 throw std::runtime_error("Keyword not found");
159}
160
161/**
162 * @brief An API to process encoding of a keyword.
163 *
Souvik Royf277d6a2025-02-20 00:08:43 -0600164 * @param[in] i_keyword - Keyword to be processed.
165 * @param[in] i_encoding - Type of encoding.
166 *
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500167 * @return Value after being processed for encoded type.
168 */
Souvik Royf277d6a2025-02-20 00:08:43 -0600169inline std::string encodeKeyword(const std::string& i_keyword,
170 const std::string& i_encoding) noexcept
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500171{
172 // Default value is keyword value
Souvik Royf277d6a2025-02-20 00:08:43 -0600173 std::string l_result(i_keyword.begin(), i_keyword.end());
174 try
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500175 {
Souvik Royf277d6a2025-02-20 00:08:43 -0600176 if (i_encoding == "MAC")
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500177 {
Souvik Royf277d6a2025-02-20 00:08:43 -0600178 l_result.clear();
179 size_t l_firstByte = i_keyword[0];
180 l_result += commonUtility::toHex(l_firstByte >> 4);
181 l_result += commonUtility::toHex(l_firstByte & 0x0f);
182 for (size_t i = 1; i < i_keyword.size(); ++i)
183 {
184 l_result += ":";
185 l_result += commonUtility::toHex(i_keyword[i] >> 4);
186 l_result += commonUtility::toHex(i_keyword[i] & 0x0f);
187 }
188 }
189 else if (i_encoding == "DATE")
190 {
191 // Date, represent as
192 // <year>-<month>-<day> <hour>:<min>
193 l_result.clear();
194 static constexpr uint8_t skipPrefix = 3;
195
196 auto strItr = i_keyword.begin();
197 advance(strItr, skipPrefix);
198 for_each(strItr, i_keyword.end(),
199 [&l_result](size_t c) { l_result += c; });
200
201 l_result.insert(constants::BD_YEAR_END, 1, '-');
202 l_result.insert(constants::BD_MONTH_END, 1, '-');
203 l_result.insert(constants::BD_DAY_END, 1, ' ');
204 l_result.insert(constants::BD_HOUR_END, 1, ':');
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500205 }
206 }
Souvik Royf277d6a2025-02-20 00:08:43 -0600207 catch (const std::exception& l_ex)
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500208 {
Souvik Royf277d6a2025-02-20 00:08:43 -0600209 l_result.clear();
210 logging::logMessage("Failed to encode keyword [" + i_keyword +
211 "]. Error: " + l_ex.what());
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500212 }
213
Souvik Royf277d6a2025-02-20 00:08:43 -0600214 return l_result;
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500215}
216
217/**
218 * @brief Helper function to insert or merge in map.
219 *
220 * This method checks in an interface if the given interface exists. If the
221 * interface key already exists, property map is inserted corresponding to it.
222 * If the key does'nt exist then given interface and property map pair is newly
223 * created. If the property present in propertymap already exist in the
224 * InterfaceMap, then the new property value is ignored.
225 *
Souvik Royfa47e6c2025-02-20 00:17:25 -0600226 * @param[in,out] io_map - Interface map.
227 * @param[in] i_interface - Interface to be processed.
228 * @param[in] i_propertyMap - new property map that needs to be emplaced.
229 *
230 * @return On success returns 0, otherwise returns -1.
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500231 */
Souvik Royfa47e6c2025-02-20 00:17:25 -0600232inline int insertOrMerge(types::InterfaceMap& io_map,
233 const std::string& i_interface,
234 types::PropertyMap&& i_propertyMap) noexcept
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500235{
Souvik Royfa47e6c2025-02-20 00:17:25 -0600236 int l_rc{constants::FAILURE};
237 try
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500238 {
Souvik Royfa47e6c2025-02-20 00:17:25 -0600239 if (io_map.find(i_interface) != io_map.end())
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500240 {
Souvik Royfa47e6c2025-02-20 00:17:25 -0600241 auto& l_prop = io_map.at(i_interface);
242 std::for_each(i_propertyMap.begin(), i_propertyMap.end(),
243 [&l_prop](auto l_keyValue) {
244 l_prop[l_keyValue.first] = l_keyValue.second;
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500245 });
246 }
Souvik Royfa47e6c2025-02-20 00:17:25 -0600247 else
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500248 {
Souvik Royfa47e6c2025-02-20 00:17:25 -0600249 io_map.emplace(i_interface, i_propertyMap);
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500250 }
Souvik Royfa47e6c2025-02-20 00:17:25 -0600251
252 l_rc = constants::SUCCESS;
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500253 }
Souvik Royfa47e6c2025-02-20 00:17:25 -0600254 catch (const std::exception& l_ex)
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500255 {
Souvik Royfa47e6c2025-02-20 00:17:25 -0600256 // ToDo:: Log PEL
257 logging::logMessage(
258 "Inserting properties into interface[" + i_interface +
259 "] map failed, reason: " + std::string(l_ex.what()));
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500260 }
Souvik Royfa47e6c2025-02-20 00:17:25 -0600261 return l_rc;
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500262}
263
264/**
265 * @brief API to expand unpanded location code.
266 *
267 * Note: The API handles all the exception internally, in case of any error
268 * unexpanded location code will be returned as it is.
269 *
270 * @param[in] unexpandedLocationCode - Unexpanded location code.
271 * @param[in] parsedVpdMap - Parsed VPD map.
272 * @return Expanded location code. In case of any error, unexpanded is returned
273 * as it is.
274 */
Patrick Williams43fedab2025-02-03 14:28:05 -0500275inline std::string getExpandedLocationCode(
276 const std::string& unexpandedLocationCode,
277 const types::VPDMapVariant& parsedVpdMap)
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500278{
279 auto expanded{unexpandedLocationCode};
280
281 try
282 {
283 // Expanded location code is formed by combining two keywords
284 // depending on type in unexpanded one. Second one is always "SE".
285 std::string kwd1, kwd2{constants::kwdSE};
286
287 // interface to search for required keywords;
288 std::string kwdInterface;
289
290 // record which holds the required keywords.
291 std::string recordName;
292
293 auto pos = unexpandedLocationCode.find("fcs");
294 if (pos != std::string::npos)
295 {
296 kwd1 = constants::kwdFC;
297 kwdInterface = constants::vcenInf;
298 recordName = constants::recVCEN;
299 }
300 else
301 {
302 pos = unexpandedLocationCode.find("mts");
303 if (pos != std::string::npos)
304 {
305 kwd1 = constants::kwdTM;
306 kwdInterface = constants::vsysInf;
307 recordName = constants::recVSYS;
308 }
309 else
310 {
311 throw std::runtime_error(
312 "Error detecting type of unexpanded location code.");
313 }
314 }
315
316 std::string firstKwdValue, secondKwdValue;
317
318 if (auto ipzVpdMap = std::get_if<types::IPZVpdMap>(&parsedVpdMap);
319 ipzVpdMap && (*ipzVpdMap).find(recordName) != (*ipzVpdMap).end())
320 {
321 auto itrToVCEN = (*ipzVpdMap).find(recordName);
322 // The exceptions will be cautght at end.
323 getKwVal(itrToVCEN->second, kwd1, firstKwdValue);
324 getKwVal(itrToVCEN->second, kwd2, secondKwdValue);
325 }
326 else
327 {
328 std::array<const char*, 1> interfaceList = {kwdInterface.c_str()};
329
330 types::MapperGetObject mapperRetValue = dbusUtility::getObjectMap(
331 std::string(constants::systemVpdInvPath), interfaceList);
332
333 if (mapperRetValue.empty())
334 {
335 throw std::runtime_error("Mapper failed to get service");
336 }
337
338 const std::string& serviceName = std::get<0>(mapperRetValue.at(0));
339
340 auto retVal = dbusUtility::readDbusProperty(
341 serviceName, std::string(constants::systemVpdInvPath),
342 kwdInterface, kwd1);
343
344 if (auto kwdVal = std::get_if<types::BinaryVector>(&retVal))
345 {
346 firstKwdValue.assign(
347 reinterpret_cast<const char*>(kwdVal->data()),
348 kwdVal->size());
349 }
350 else
351 {
352 throw std::runtime_error(
353 "Failed to read value of " + kwd1 + " from Bus");
354 }
355
356 retVal = dbusUtility::readDbusProperty(
357 serviceName, std::string(constants::systemVpdInvPath),
358 kwdInterface, kwd2);
359
360 if (auto kwdVal = std::get_if<types::BinaryVector>(&retVal))
361 {
362 secondKwdValue.assign(
363 reinterpret_cast<const char*>(kwdVal->data()),
364 kwdVal->size());
365 }
366 else
367 {
368 throw std::runtime_error(
369 "Failed to read value of " + kwd2 + " from Bus");
370 }
371 }
372
373 if (unexpandedLocationCode.find("fcs") != std::string::npos)
374 {
375 // TODO: See if ND0 can be placed in the JSON
376 expanded.replace(
377 pos, 3, firstKwdValue.substr(0, 4) + ".ND0." + secondKwdValue);
378 }
379 else
380 {
381 replace(firstKwdValue.begin(), firstKwdValue.end(), '-', '.');
382 expanded.replace(pos, 3, firstKwdValue + "." + secondKwdValue);
383 }
384 }
385 catch (const std::exception& ex)
386 {
387 logging::logMessage("Failed to expand location code with exception: " +
388 std::string(ex.what()));
389 }
390
391 return expanded;
392}
393
394/**
395 * @brief An API to get VPD in a vector.
396 *
397 * The vector is required by the respective parser to fill the VPD map.
398 * Note: API throws exception in case of failure. Caller needs to handle.
399 *
400 * @param[in] vpdFilePath - EEPROM path of the FRU.
401 * @param[out] vpdVector - VPD in vector form.
402 * @param[in] vpdStartOffset - Offset of VPD data in EEPROM.
403 */
404inline void getVpdDataInVector(const std::string& vpdFilePath,
405 types::BinaryVector& vpdVector,
406 size_t& vpdStartOffset)
407{
408 try
409 {
410 std::fstream vpdFileStream;
411 vpdFileStream.exceptions(
412 std::ifstream::badbit | std::ifstream::failbit);
413 vpdFileStream.open(vpdFilePath, std::ios::in | std::ios::binary);
414 auto vpdSizeToRead = std::min(std::filesystem::file_size(vpdFilePath),
415 static_cast<uintmax_t>(65504));
416 vpdVector.resize(vpdSizeToRead);
417
418 vpdFileStream.seekg(vpdStartOffset, std::ios_base::beg);
419 vpdFileStream.read(reinterpret_cast<char*>(&vpdVector[0]),
420 vpdSizeToRead);
421
422 vpdVector.resize(vpdFileStream.gcount());
423 vpdFileStream.clear(std::ios_base::eofbit);
424 }
425 catch (const std::ifstream::failure& fail)
426 {
427 std::cerr << "Exception in file handling [" << vpdFilePath
428 << "] error : " << fail.what();
429 throw;
430 }
431}
432
433/**
434 * @brief An API to get D-bus representation of given VPD keyword.
435 *
436 * @param[in] i_keywordName - VPD keyword name.
437 *
438 * @return D-bus representation of given keyword.
439 */
440inline std::string getDbusPropNameForGivenKw(const std::string& i_keywordName)
441{
442 // Check for "#" prefixed VPD keyword.
443 if ((i_keywordName.size() == vpd::constants::TWO_BYTES) &&
444 (i_keywordName.at(0) == constants::POUND_KW))
445 {
446 // D-bus doesn't support "#". Replace "#" with "PD_" for those "#"
447 // prefixed keywords.
448 return (std::string(constants::POUND_KW_PREFIX) +
449 i_keywordName.substr(1));
450 }
451
452 // Return the keyword name back, if D-bus representation is same as the VPD
453 // keyword name.
454 return i_keywordName;
455}
456
457/**
458 * @brief API to find CCIN in parsed VPD map.
459 *
460 * Few FRUs need some special handling. To identify those FRUs CCIN are used.
461 * The API will check from parsed VPD map if the FRU is the one with desired
462 * CCIN.
463 *
464 * @throw std::runtime_error
465 * @throw DataException
466 *
467 * @param[in] i_JsonObject - Any JSON which contains CCIN tag to match.
468 * @param[in] i_parsedVpdMap - Parsed VPD map.
469 * @return True if found, false otherwise.
470 */
471inline bool findCcinInVpd(const nlohmann::json& i_JsonObject,
472 const types::VPDMapVariant& i_parsedVpdMap)
473{
474 if (i_JsonObject.empty())
475 {
476 throw std::runtime_error("Json object is empty. Can't find CCIN");
477 }
478
479 if (auto l_ipzVPDMap = std::get_if<types::IPZVpdMap>(&i_parsedVpdMap))
480 {
481 auto l_itrToRec = (*l_ipzVPDMap).find("VINI");
482 if (l_itrToRec == (*l_ipzVPDMap).end())
483 {
484 throw DataException(
485 "VINI record not found in parsed VPD. Can't find CCIN");
486 }
487
488 std::string l_ccinFromVpd;
489 vpdSpecificUtility::getKwVal(l_itrToRec->second, "CC", l_ccinFromVpd);
490 if (l_ccinFromVpd.empty())
491 {
492 throw DataException("Empty CCIN value in VPD map. Can't find CCIN");
493 }
494
495 transform(l_ccinFromVpd.begin(), l_ccinFromVpd.end(),
496 l_ccinFromVpd.begin(), ::toupper);
497
498 for (std::string l_ccinValue : i_JsonObject["ccin"])
499 {
500 transform(l_ccinValue.begin(), l_ccinValue.end(),
501 l_ccinValue.begin(), ::toupper);
502
503 if (l_ccinValue.compare(l_ccinFromVpd) ==
504 constants::STR_CMP_SUCCESS)
505 {
506 // CCIN found
507 return true;
508 }
509 }
510
511 logging::logMessage("No match found for CCIN");
512 return false;
513 }
514
515 logging::logMessage("VPD type not supported. Can't find CCIN");
516 return false;
517}
518
519/**
520 * @brief API to reset data of a FRU populated under PIM.
521 *
522 * This API resets the data for particular interfaces of a FRU under PIM.
523 *
524 * @param[in] i_objectPath - DBus object path of the FRU.
525 * @param[in] io_interfaceMap - Interface and its properties map.
526 */
527inline void resetDataUnderPIM(const std::string& i_objectPath,
528 types::InterfaceMap& io_interfaceMap)
529{
530 try
531 {
532 std::array<const char*, 0> l_interfaces;
533 const types::MapperGetObject& l_getObjectMap =
534 dbusUtility::getObjectMap(i_objectPath, l_interfaces);
535
536 const std::vector<std::string>& l_vpdRelatedInterfaces{
537 constants::operationalStatusInf, constants::inventoryItemInf,
538 constants::assetInf};
539
540 for (const auto& [l_service, l_interfaceList] : l_getObjectMap)
541 {
542 if (l_service.compare(constants::pimServiceName) !=
543 constants::STR_CMP_SUCCESS)
544 {
545 continue;
546 }
547
548 for (const auto& l_interface : l_interfaceList)
549 {
550 if ((l_interface.find(constants::ipzVpdInf) !=
551 std::string::npos) ||
552 ((std::find(l_vpdRelatedInterfaces.begin(),
553 l_vpdRelatedInterfaces.end(), l_interface)) !=
554 l_vpdRelatedInterfaces.end()))
555 {
556 const types::PropertyMap& l_propertyValueMap =
557 dbusUtility::getPropertyMap(l_service, i_objectPath,
558 l_interface);
559
560 types::PropertyMap l_propertyMap;
561
562 for (const auto& l_aProperty : l_propertyValueMap)
563 {
564 const std::string& l_propertyName = l_aProperty.first;
565 const auto& l_propertyValue = l_aProperty.second;
566
567 if (std::holds_alternative<types::BinaryVector>(
568 l_propertyValue))
569 {
570 l_propertyMap.emplace(l_propertyName,
571 types::BinaryVector{});
572 }
573 else if (std::holds_alternative<std::string>(
574 l_propertyValue))
575 {
576 l_propertyMap.emplace(l_propertyName,
577 std::string{});
578 }
579 else if (std::holds_alternative<bool>(l_propertyValue))
580 {
581 // ToDo -- Update the functional status property
582 // to true.
583 if (l_propertyName.compare("Present") ==
584 constants::STR_CMP_SUCCESS)
585 {
586 l_propertyMap.emplace(l_propertyName, false);
587 }
588 }
589 }
590 io_interfaceMap.emplace(l_interface,
591 std::move(l_propertyMap));
592 }
593 }
594 }
595 }
596 catch (const std::exception& l_ex)
597 {
598 logging::logMessage("Failed to remove VPD for FRU: " + i_objectPath +
599 " with error: " + std::string(l_ex.what()));
600 }
601}
Sunny Srivastava78c91072025-02-05 14:09:50 +0530602
603/**
604 * @brief API to detect pass1 planar type.
605 *
606 * Based on HW version and IM keyword, This API detects is it is a pass1 planar
607 * or not.
608 *
609 * @return True if pass 1 planar, false otherwise.
610 */
611inline bool isPass1Planar()
612{
613 auto l_retVal = dbusUtility::readDbusProperty(
614 constants::pimServiceName, constants::systemVpdInvPath,
615 constants::viniInf, constants::kwdHW);
616
617 auto l_hwVer = std::get_if<types::BinaryVector>(&l_retVal);
618
619 l_retVal = dbusUtility::readDbusProperty(
620 constants::pimServiceName, constants::systemInvPath, constants::vsbpInf,
621 constants::kwdIM);
622
623 auto l_imValue = std::get_if<types::BinaryVector>(&l_retVal);
624
625 if (l_hwVer && l_imValue)
626 {
627 types::BinaryVector everest{80, 00, 48, 00};
628 types::BinaryVector fuji{96, 00, 32, 00};
629
630 if (((*l_imValue) == everest) || ((*l_imValue) == fuji))
631 {
632 if ((*l_hwVer).at(1) < constants::VALUE_21)
633 {
634 return true;
635 }
636 }
637 else if ((*l_hwVer).at(1) < constants::VALUE_2)
638 {
639 return true;
640 }
641 }
642
643 return false;
644}
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500645} // namespace vpdSpecificUtility
646} // namespace vpd