blob: 58706594b0bb447418278b3e69b72c2bb00d8c20 [file] [log] [blame]
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +05301#include "vpd_tool_impl.hpp"
2
Priyanga Ramasamy38031312021-10-07 16:39:13 -05003#include "impl.hpp"
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -05004#include "parser_factory.hpp"
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +05305#include "vpd_exceptions.hpp"
6
PriyangaRamasamycdf943c2020-03-18 02:25:30 +05307#include <cstdlib>
8#include <filesystem>
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +05309#include <iostream>
10#include <sdbusplus/bus.hpp>
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +053011#include <variant>
12#include <vector>
13
14using namespace std;
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +053015using namespace openpower::vpd;
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +053016using namespace inventory;
17using namespace openpower::vpd::manager::editor;
PriyangaRamasamycdf943c2020-03-18 02:25:30 +053018namespace fs = std::filesystem;
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +053019using json = nlohmann::json;
20using namespace openpower::vpd::exceptions;
Priyanga Ramasamy38031312021-10-07 16:39:13 -050021using namespace openpower::vpd::parser;
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -050022using namespace openpower::vpd::parser::factory;
23using namespace openpower::vpd::parser::interface;
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +053024
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -060025bool VpdTool::fileToVector(Binary& data)
26{
27 try
28 {
29 std::ifstream file(value, std::ifstream::in);
30
31 if (file)
32 {
33 std::string line;
34 while (std::getline(file, line))
35 {
36 std::istringstream iss(line);
37 std::string byteStr;
38 while (iss >> std::setw(2) >> std::hex >> byteStr)
39 {
40 uint8_t byte = strtoul(byteStr.c_str(), nullptr, 16);
41 data.emplace(data.end(), byte);
42 }
43 }
44 return true;
45 }
46 else
47 {
48 std::cerr << "Unable to open the given file " << value << std::endl;
49 }
50 }
51 catch (std::exception& e)
52 {
53 std::cerr << e.what();
54 }
55 return false;
56}
57
58bool VpdTool::copyStringToFile(const std::string& input)
59{
60 try
61 {
62 std::ofstream outFile(value, std::ofstream::out);
63
64 if (outFile.is_open())
65 {
66 std::string hexString = input;
67 if (input.substr(0, 2) == "0x")
68 {
69 // truncating prefix 0x
70 hexString = input.substr(2);
71 }
72 outFile.write(hexString.c_str(), hexString.length());
73 }
74 else
75 {
76 std::cerr << "Error opening output file " << value << std::endl;
77 return false;
78 }
79
80 outFile.close();
81 }
82 catch (std::exception& e)
83 {
84 std::cerr << e.what();
85 return false;
86 }
87 return true;
88}
89
Priyanga Ramasamy6d5e7342022-10-14 07:17:25 -050090static void
91 getVPDInMap(const std::string& vpdPath,
92 std::unordered_map<std::string, DbusPropertyMap>& vpdMap,
93 json& js, const std::string& invPath)
94{
95 auto jsonToParse = INVENTORY_JSON_DEFAULT;
96 if (fs::exists(INVENTORY_JSON_SYM_LINK))
97 {
98 jsonToParse = INVENTORY_JSON_SYM_LINK;
99 }
100
101 std::ifstream inventoryJson(jsonToParse);
102 if (!inventoryJson)
103 {
104 throw std::runtime_error("VPD JSON file not found");
105 }
106
107 try
108 {
109 js = json::parse(inventoryJson);
110 }
111 catch (const json::parse_error& ex)
112 {
113 throw std::runtime_error("VPD JSON parsing failed");
114 }
115
116 Binary vpdVector{};
117
girik18bb9852022-11-16 05:48:13 -0600118 uint32_t vpdStartOffset = 0;
Priyanga Ramasamy6d5e7342022-10-14 07:17:25 -0500119 vpdVector = getVpdDataInVector(js, constants::systemVpdFilePath);
girik18bb9852022-11-16 05:48:13 -0600120 ParserInterface* parser = ParserFactory::getParser(
121 vpdVector, invPath, constants::systemVpdFilePath, vpdStartOffset);
Priyanga Ramasamy6d5e7342022-10-14 07:17:25 -0500122 auto parseResult = parser->parse();
123 ParserFactory::freeParser(parser);
124
125 if (auto pVal = std::get_if<Store>(&parseResult))
126 {
127 vpdMap = pVal->getVpdMap();
128 }
129 else
130 {
131 std::string err =
132 vpdPath + " is not of type IPZ VPD. Unable to parse the VPD.";
133 throw std::runtime_error(err);
134 }
135}
136
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530137Binary VpdTool::toBinary(const std::string& value)
138{
139 Binary val{};
140 if (value.find("0x") == string::npos)
141 {
142 val.assign(value.begin(), value.end());
143 }
144 else if (value.find("0x") != string::npos)
145 {
146 stringstream ss;
147 ss.str(value.substr(2));
148 string byteStr{};
149
Priyanga Ramasamyec912e62021-12-15 22:47:51 -0600150 if (value.length() % 2 != 0)
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530151 {
Priyanga Ramasamyec912e62021-12-15 22:47:51 -0600152 throw runtime_error(
153 "VPD-TOOL write option accepts 2 digit hex numbers. (Eg. 0x1 "
154 "should be given as 0x01). Aborting the write operation.");
155 }
156
157 if (value.find_first_not_of("0123456789abcdefABCDEF", 2) !=
158 std::string::npos)
159 {
160 throw runtime_error("Provide a valid hexadecimal input.");
161 }
162
163 while (ss >> setw(2) >> byteStr)
164 {
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530165 uint8_t byte = strtoul(byteStr.c_str(), nullptr, 16);
166
167 val.push_back(byte);
168 }
169 }
170
171 else
172 {
173 throw runtime_error("The value to be updated should be either in ascii "
174 "or in hex. Refer --help option");
175 }
176 return val;
177}
PriyangaRamasamycdf943c2020-03-18 02:25:30 +0530178
PriyangaRamasamy6ee637a2021-02-12 04:49:02 -0600179void VpdTool::printReturnCode(int returnCode)
180{
181 if (returnCode)
182 {
183 cout << "\n Command failed with the return code " << returnCode
184 << ". Continuing the execution. " << endl;
185 }
186}
187
PriyangaRamasamycdf943c2020-03-18 02:25:30 +0530188void VpdTool::eraseInventoryPath(string& fru)
189{
190 // Power supply frupath comes with INVENTORY_PATH appended in prefix.
191 // Stripping it off inorder to avoid INVENTORY_PATH duplication
192 // during getVINIProperties() execution.
193 fru.erase(0, sizeof(INVENTORY_PATH) - 1);
194}
195
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530196void VpdTool::debugger(json output)
197{
198 cout << output.dump(4) << '\n';
199}
200
201auto VpdTool::makeDBusCall(const string& objectName, const string& interface,
202 const string& kw)
203{
204 auto bus = sdbusplus::bus::new_default();
205 auto properties =
206 bus.new_method_call(INVENTORY_MANAGER_SERVICE, objectName.c_str(),
207 "org.freedesktop.DBus.Properties", "Get");
208 properties.append(interface);
209 properties.append(kw);
210 auto result = bus.call(properties);
211
212 if (result.is_method_error())
213 {
214 throw runtime_error("Get api failed");
215 }
216 return result;
217}
218
PriyangaRamasamy8cc5b152021-06-03 13:05:17 -0500219json VpdTool::getVINIProperties(string invPath)
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530220{
221 variant<Binary> response;
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530222 json kwVal = json::object({});
223
224 vector<string> keyword{"CC", "SN", "PN", "FN", "DR"};
225 string interface = "com.ibm.ipzvpd.VINI";
PriyangaRamasamycdf943c2020-03-18 02:25:30 +0530226 string objectName = {};
227
228 if (invPath.find(INVENTORY_PATH) != string::npos)
229 {
230 objectName = invPath;
231 eraseInventoryPath(invPath);
232 }
233 else
234 {
235 objectName = INVENTORY_PATH + invPath;
236 }
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530237 for (string kw : keyword)
238 {
239 try
240 {
241 makeDBusCall(objectName, interface, kw).read(response);
242
243 if (auto vec = get_if<Binary>(&response))
244 {
PriyangaRamasamy887a42a2020-09-03 00:33:57 +0530245 string printableVal = getPrintableValue(*vec);
246 kwVal.emplace(kw, printableVal);
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530247 }
248 }
Patrick Williams2eb01762022-07-22 19:26:56 -0500249 catch (const sdbusplus::exception_t& e)
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530250 {
PriyangaRamasamy8cc5b152021-06-03 13:05:17 -0500251 if (string(e.name()) ==
252 string("org.freedesktop.DBus.Error.UnknownObject"))
253 {
254 kwVal.emplace(invPath, json::object({}));
255 objFound = false;
256 break;
257 }
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530258 }
259 }
260
PriyangaRamasamy8cc5b152021-06-03 13:05:17 -0500261 return kwVal;
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530262}
263
PriyangaRamasamy8cc5b152021-06-03 13:05:17 -0500264void VpdTool::getExtraInterfaceProperties(const string& invPath,
265 const string& extraInterface,
266 const json& prop, json& output)
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530267{
268 variant<string> response;
269
270 string objectName = INVENTORY_PATH + invPath;
271
272 for (const auto& itProp : prop.items())
273 {
274 string kw = itProp.key();
275 try
276 {
277 makeDBusCall(objectName, extraInterface, kw).read(response);
278
279 if (auto str = get_if<string>(&response))
280 {
281 output.emplace(kw, *str);
282 }
283 }
Patrick Williams2eb01762022-07-22 19:26:56 -0500284 catch (const sdbusplus::exception_t& e)
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530285 {
PriyangaRamasamy8cc5b152021-06-03 13:05:17 -0500286 if (std::string(e.name()) ==
287 std::string("org.freedesktop.DBus.Error.UnknownObject"))
288 {
289 objFound = false;
290 break;
291 }
292 else if (std::string(e.name()) ==
293 std::string("org.freedesktop.DBus.Error.UnknownProperty"))
294 {
295 output.emplace(kw, "");
296 }
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530297 }
298 }
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530299}
300
301json VpdTool::interfaceDecider(json& itemEEPROM)
302{
303 if (itemEEPROM.find("inventoryPath") == itemEEPROM.end())
304 {
305 throw runtime_error("Inventory Path not found");
306 }
307
308 if (itemEEPROM.find("extraInterfaces") == itemEEPROM.end())
309 {
310 throw runtime_error("Extra Interfaces not found");
311 }
312
PriyangaRamasamy8cc5b152021-06-03 13:05:17 -0500313 json subOutput = json::object({});
Alpana Kumarib6965f12020-06-01 00:32:21 -0500314 fruType = "FRU";
315
PriyangaRamasamy8cc5b152021-06-03 13:05:17 -0500316 json j;
317 objFound = true;
318 string invPath = itemEEPROM.at("inventoryPath");
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530319
PriyangaRamasamy8cc5b152021-06-03 13:05:17 -0500320 j = getVINIProperties(invPath);
321
322 if (objFound)
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530323 {
PriyangaRamasamy8cc5b152021-06-03 13:05:17 -0500324 subOutput.insert(j.begin(), j.end());
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530325 json js;
PriyangaRamasamy8cc5b152021-06-03 13:05:17 -0500326 if (itemEEPROM.find("type") != itemEEPROM.end())
327 {
328 fruType = itemEEPROM.at("type");
329 }
330 js.emplace("TYPE", fruType);
331
332 if (invPath.find("powersupply") != string::npos)
333 {
334 js.emplace("type", POWER_SUPPLY_TYPE_INTERFACE);
335 }
336 else if (invPath.find("fan") != string::npos)
337 {
338 js.emplace("type", FAN_INTERFACE);
339 }
340
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530341 for (const auto& ex : itemEEPROM["extraInterfaces"].items())
342 {
343 if (!(ex.value().is_null()))
344 {
Priyanga Ramasamydacaa472021-10-07 12:22:41 -0500345 // TODO: Remove this if condition check once inventory json is
346 // updated with xyz location code interface.
347 if (ex.key() == "com.ibm.ipzvpd.Location")
348 {
349 getExtraInterfaceProperties(
350 invPath,
351 "xyz.openbmc_project.Inventory.Decorator.LocationCode",
352 ex.value(), js);
353 }
354 else
355 {
356 getExtraInterfaceProperties(invPath, ex.key(), ex.value(),
357 js);
358 }
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530359 }
PriyangaRamasamy8cc5b152021-06-03 13:05:17 -0500360 if ((ex.key().find("Item") != string::npos) &&
361 (ex.value().is_null()))
362 {
363 js.emplace("type", ex.key());
364 }
365 subOutput.insert(js.begin(), js.end());
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530366 }
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530367 }
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500368 return subOutput;
369}
370
Priyanga Ramasamyd90aadb2023-03-28 12:25:14 -0500371json VpdTool::getPresentPropJson(const std::string& invPath)
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500372{
373 std::variant<bool> response;
Priyanga Ramasamyd90aadb2023-03-28 12:25:14 -0500374 std::string presence = "Unknown";
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500375
Priyanga Ramasamyd90aadb2023-03-28 12:25:14 -0500376 try
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500377 {
Priyanga Ramasamyd90aadb2023-03-28 12:25:14 -0500378 makeDBusCall(invPath, "xyz.openbmc_project.Inventory.Item", "Present")
379 .read(response);
380
381 if (auto pVal = get_if<bool>(&response))
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500382 {
Priyanga Ramasamyd90aadb2023-03-28 12:25:14 -0500383 presence = *pVal ? "true" : "false";
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500384 }
385 }
Priyanga Ramasamyd90aadb2023-03-28 12:25:14 -0500386 catch (const sdbusplus::exception::SdBusError& e)
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500387 {
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600388 presence = "Unknown";
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500389 }
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600390
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500391 json js;
392 js.emplace("Present", presence);
393 return js;
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530394}
395
396json VpdTool::parseInvJson(const json& jsObject, char flag, string fruPath)
397{
398 json output = json::object({});
399 bool validObject = false;
400
401 if (jsObject.find("frus") == jsObject.end())
402 {
403 throw runtime_error("Frus missing in Inventory json");
404 }
405 else
406 {
407 for (const auto& itemFRUS : jsObject["frus"].items())
408 {
409 for (auto itemEEPROM : itemFRUS.value())
410 {
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500411 json subOutput = json::object({});
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530412 try
413 {
414 if (flag == 'O')
415 {
416 if (itemEEPROM.find("inventoryPath") ==
417 itemEEPROM.end())
418 {
419 throw runtime_error("Inventory Path not found");
420 }
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530421 else if (itemEEPROM.at("inventoryPath") == fruPath)
422 {
423 validObject = true;
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500424 subOutput = interfaceDecider(itemEEPROM);
425 json presentJs = getPresentPropJson(
Priyanga Ramasamyd90aadb2023-03-28 12:25:14 -0500426 "/xyz/openbmc_project/inventory" + fruPath);
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500427 subOutput.insert(presentJs.begin(),
428 presentJs.end());
429 output.emplace(fruPath, subOutput);
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530430 return output;
431 }
432 }
433 else
434 {
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500435 subOutput = interfaceDecider(itemEEPROM);
436 json presentJs = getPresentPropJson(
437 "/xyz/openbmc_project/inventory" +
Priyanga Ramasamyd90aadb2023-03-28 12:25:14 -0500438 string(itemEEPROM.at("inventoryPath")));
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500439 subOutput.insert(presentJs.begin(), presentJs.end());
440 output.emplace(string(itemEEPROM.at("inventoryPath")),
441 subOutput);
442 }
443 }
Patrick Williams8e15b932021-10-06 13:04:22 -0500444 catch (const exception& e)
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530445 {
446 cerr << e.what();
447 }
448 }
449 }
450 if ((flag == 'O') && (!validObject))
451 {
452 throw runtime_error(
453 "Invalid object path. Refer --dumpInventory/-i option.");
454 }
455 }
456 return output;
457}
458
459void VpdTool::dumpInventory(const nlohmann::basic_json<>& jsObject)
460{
461 char flag = 'I';
PriyangaRamasamycdf943c2020-03-18 02:25:30 +0530462 json output = json::array({});
463 output.emplace_back(parseInvJson(jsObject, flag, ""));
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530464 debugger(output);
465}
466
467void VpdTool::dumpObject(const nlohmann::basic_json<>& jsObject)
468{
469 char flag = 'O';
PriyangaRamasamycdf943c2020-03-18 02:25:30 +0530470 json output = json::array({});
Santosh Puranikd5d52bb2020-07-28 15:08:10 +0530471 output.emplace_back(parseInvJson(jsObject, flag, fruPath));
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530472 debugger(output);
473}
PriyangaRamasamy02d4d4e2020-02-24 14:54:45 +0530474
475void VpdTool::readKeyword()
476{
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600477 const std::string& kw = getDbusNameForThisKw(keyword);
478
PriyangaRamasamy02d4d4e2020-02-24 14:54:45 +0530479 string interface = "com.ibm.ipzvpd.";
480 variant<Binary> response;
481
482 try
483 {
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600484 makeDBusCall(INVENTORY_PATH + fruPath, interface + recordName, kw)
PriyangaRamasamy02d4d4e2020-02-24 14:54:45 +0530485 .read(response);
486
PriyangaRamasamy887a42a2020-09-03 00:33:57 +0530487 string printableVal{};
PriyangaRamasamy02d4d4e2020-02-24 14:54:45 +0530488 if (auto vec = get_if<Binary>(&response))
489 {
PriyangaRamasamy887a42a2020-09-03 00:33:57 +0530490 printableVal = getPrintableValue(*vec);
PriyangaRamasamy02d4d4e2020-02-24 14:54:45 +0530491 }
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600492
493 if (!value.empty())
494 {
495 if (copyStringToFile(printableVal))
496 {
497 std::cout << "Value read is saved in the file " << value
498 << std::endl;
499 return;
500 }
501 else
502 {
503 std::cerr << "Error while saving the read value in file. "
504 "Displaying the read value on console"
505 << std::endl;
506 }
507 }
508
509 json output = json::object({});
510 json kwVal = json::object({});
PriyangaRamasamy887a42a2020-09-03 00:33:57 +0530511 kwVal.emplace(keyword, printableVal);
PriyangaRamasamy02d4d4e2020-02-24 14:54:45 +0530512
513 output.emplace(fruPath, kwVal);
514
515 debugger(output);
516 }
Patrick Williams8e15b932021-10-06 13:04:22 -0500517 catch (const json::exception& e)
PriyangaRamasamy02d4d4e2020-02-24 14:54:45 +0530518 {
GiridhariKrishnan63639102023-03-02 05:55:47 -0600519 std::cout << "Keyword Value: " << keyword << std::endl;
520 std::cout << e.what() << std::endl;
PriyangaRamasamy02d4d4e2020-02-24 14:54:45 +0530521 }
522}
PriyangaRamasamyd09d2ec2020-03-12 14:11:50 +0530523
524int VpdTool::updateKeyword()
525{
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600526 Binary val;
527
528 if (std::filesystem::exists(value))
529 {
530 if (!fileToVector(val))
531 {
532 std::cout << "Keyword " << keyword << " update failed."
533 << std::endl;
534 return 1;
535 }
536 }
537 else
538 {
539 val = toBinary(value);
540 }
541
PriyangaRamasamyd09d2ec2020-03-12 14:11:50 +0530542 auto bus = sdbusplus::bus::new_default();
543 auto properties =
544 bus.new_method_call(BUSNAME, OBJPATH, IFACE, "WriteKeyword");
545 properties.append(static_cast<sdbusplus::message::object_path>(fruPath));
546 properties.append(recordName);
547 properties.append(keyword);
548 properties.append(val);
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600549
550 // When there is a request to write 10K bytes, there occurs a delay in dbus
551 // call which leads to dbus timeout exception. To avoid such exceptions
552 // increase the timeout period from default 25 seconds to 60 seconds.
553 auto timeoutInMicroSeconds = 60 * 1000000L;
554 auto result = bus.call(properties, timeoutInMicroSeconds);
PriyangaRamasamyd09d2ec2020-03-12 14:11:50 +0530555
556 if (result.is_method_error())
557 {
558 throw runtime_error("Get api failed");
559 }
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600560 std::cout << "Data updated successfully " << std::endl;
PriyangaRamasamyd09d2ec2020-03-12 14:11:50 +0530561 return 0;
562}
PriyangaRamasamy0407b172020-03-31 13:57:18 +0530563
564void VpdTool::forceReset(const nlohmann::basic_json<>& jsObject)
565{
566 for (const auto& itemFRUS : jsObject["frus"].items())
567 {
568 for (const auto& itemEEPROM : itemFRUS.value().items())
569 {
570 string fru = itemEEPROM.value().at("inventoryPath");
571
572 fs::path fruCachePath = INVENTORY_MANAGER_CACHE;
573 fruCachePath += INVENTORY_PATH;
574 fruCachePath += fru;
575
576 try
577 {
578 for (const auto& it : fs::directory_iterator(fruCachePath))
579 {
580 if (fs::is_regular_file(it.status()))
581 {
582 fs::remove(it);
583 }
584 }
585 }
586 catch (const fs::filesystem_error& e)
587 {
588 }
589 }
590 }
591
PriyangaRamasamy6ee637a2021-02-12 04:49:02 -0600592 cout.flush();
PriyangaRamasamy0407b172020-03-31 13:57:18 +0530593 string udevRemove = "udevadm trigger -c remove -s \"*nvmem*\" -v";
PriyangaRamasamy6ee637a2021-02-12 04:49:02 -0600594 int returnCode = system(udevRemove.c_str());
595 printReturnCode(returnCode);
PriyangaRamasamy0407b172020-03-31 13:57:18 +0530596
597 string invManagerRestart =
598 "systemctl restart xyz.openbmc_project.Inventory.Manager.service";
PriyangaRamasamy6ee637a2021-02-12 04:49:02 -0600599 returnCode = system(invManagerRestart.c_str());
600 printReturnCode(returnCode);
PriyangaRamasamy0407b172020-03-31 13:57:18 +0530601
Santosh Puranik6c7a84e2022-03-09 13:42:18 +0530602 string sysVpdRestart = "systemctl restart system-vpd.service";
603 returnCode = system(sysVpdRestart.c_str());
PriyangaRamasamy6ee637a2021-02-12 04:49:02 -0600604 printReturnCode(returnCode);
PriyangaRamasamy0407b172020-03-31 13:57:18 +0530605
606 string udevAdd = "udevadm trigger -c add -s \"*nvmem*\" -v";
PriyangaRamasamy6ee637a2021-02-12 04:49:02 -0600607 returnCode = system(udevAdd.c_str());
608 printReturnCode(returnCode);
PriyangaRamasamy0407b172020-03-31 13:57:18 +0530609}
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530610
Priyanga Ramasamyc99a0b02022-06-08 14:53:39 -0500611int VpdTool::updateHardware(const uint32_t offset)
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530612{
613 int rc = 0;
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600614 Binary val;
615 if (std::filesystem::exists(value))
616 {
617 if (!fileToVector(val))
618 {
619 std::cout << "Keyword " << keyword << " update failed."
620 << std::endl;
621 return 1;
622 }
623 }
624 else
625 {
626 val = toBinary(value);
627 }
628
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530629 ifstream inventoryJson(INVENTORY_JSON_SYM_LINK);
630 try
631 {
632 auto json = nlohmann::json::parse(inventoryJson);
633 EditorImpl edit(fruPath, json, recordName, keyword);
Priyanga Ramasamyc99a0b02022-06-08 14:53:39 -0500634
635 edit.updateKeyword(val, offset, false);
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530636 }
Patrick Williams8e15b932021-10-06 13:04:22 -0500637 catch (const json::parse_error& ex)
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530638 {
639 throw(VpdJsonException("Json Parsing failed", INVENTORY_JSON_SYM_LINK));
640 }
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600641 std::cout << "Data updated successfully " << std::endl;
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530642 return rc;
Priyanga Ramasamy38031312021-10-07 16:39:13 -0500643}
644
Priyanga Ramasamyc99a0b02022-06-08 14:53:39 -0500645void VpdTool::readKwFromHw(const uint32_t& startOffset)
Priyanga Ramasamy38031312021-10-07 16:39:13 -0500646{
Priyanga Ramasamy38031312021-10-07 16:39:13 -0500647 ifstream inventoryJson(INVENTORY_JSON_SYM_LINK);
648 auto jsonFile = nlohmann::json::parse(inventoryJson);
649
Priyanga Ramasamy38031312021-10-07 16:39:13 -0500650 Binary completeVPDFile;
651 completeVPDFile.resize(65504);
652 fstream vpdFileStream;
653 vpdFileStream.open(fruPath,
654 std::ios::in | std::ios::out | std::ios::binary);
655
656 vpdFileStream.seekg(startOffset, ios_base::cur);
657 vpdFileStream.read(reinterpret_cast<char*>(&completeVPDFile[0]), 65504);
658 completeVPDFile.resize(vpdFileStream.gcount());
659 vpdFileStream.clear(std::ios_base::eofbit);
660
661 if (completeVPDFile.empty())
662 {
663 throw std::runtime_error("Invalid File");
664 }
Sunny Srivastavaf31a91b2022-06-09 08:11:29 -0500665
666 const std::string& inventoryPath =
667 jsonFile["frus"][fruPath][0]["inventoryPath"];
668
girik18bb9852022-11-16 05:48:13 -0600669 uint32_t vpdStartOffset = 0;
670 for (const auto& item : jsonFile["frus"][fruPath])
671 {
672 if (item.find("offset") != item.end())
673 {
674 vpdStartOffset = item["offset"];
675 }
676 }
677
678 Impl obj(completeVPDFile, (constants::pimPath + inventoryPath), fruPath,
679 vpdStartOffset);
Priyanga Ramasamy38031312021-10-07 16:39:13 -0500680 std::string keywordVal = obj.readKwFromHw(recordName, keyword);
681
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600682 keywordVal = getPrintableValue(keywordVal);
Priyanga Ramasamy38031312021-10-07 16:39:13 -0500683
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600684 if (keywordVal.empty())
Priyanga Ramasamy38031312021-10-07 16:39:13 -0500685 {
686 std::cerr << "The given keyword " << keyword << " or record "
687 << recordName
688 << " or both are not present in the given FRU path "
689 << fruPath << std::endl;
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600690 return;
Priyanga Ramasamy38031312021-10-07 16:39:13 -0500691 }
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600692
693 if (!value.empty())
694 {
695 if (copyStringToFile(keywordVal))
696 {
697 std::cout << "Value read is saved in the file " << value
698 << std::endl;
699 return;
700 }
701 else
702 {
703 std::cerr
704 << "Error while saving the read value in file. Displaying "
705 "the read value on console"
706 << std::endl;
707 }
708 }
709
710 json output = json::object({});
711 json kwVal = json::object({});
712 kwVal.emplace(keyword, keywordVal);
713 output.emplace(fruPath, kwVal);
714 debugger(output);
Priyanga Ramasamy38031312021-10-07 16:39:13 -0500715}
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500716
717void VpdTool::printFixSystemVPDOption(UserOption option)
718{
719 switch (option)
720 {
721 case VpdTool::EXIT:
722 cout << "\nEnter 0 => To exit successfully : ";
723 break;
Priyanga Ramasamy24942232023-01-05 04:54:59 -0600724 case VpdTool::BACKUP_DATA_FOR_ALL:
725 cout << "\n\nEnter 1 => If you choose the data on backup for all "
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500726 "mismatching record-keyword pairs";
727 break;
728 case VpdTool::SYSTEM_BACKPLANE_DATA_FOR_ALL:
Priyanga Ramasamy24942232023-01-05 04:54:59 -0600729 cout << "\nEnter 2 => If you choose the data on primary for all "
730 "mismatching record-keyword pairs";
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500731 break;
732 case VpdTool::MORE_OPTIONS:
733 cout << "\nEnter 3 => If you wish to explore more options";
734 break;
Priyanga Ramasamy24942232023-01-05 04:54:59 -0600735 case VpdTool::BACKUP_DATA_FOR_CURRENT:
736 cout << "\nEnter 4 => If you choose the data on backup as the "
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500737 "right value";
738 break;
739 case VpdTool::SYSTEM_BACKPLANE_DATA_FOR_CURRENT:
Priyanga Ramasamy24942232023-01-05 04:54:59 -0600740 cout << "\nEnter 5 => If you choose the data on primary as the "
741 "right value";
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500742 break;
743 case VpdTool::NEW_VALUE_ON_BOTH:
Priyanga Ramasamy24942232023-01-05 04:54:59 -0600744 cout << "\nEnter 6 => If you wish to enter a new value to update "
745 "both on backup and primary";
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500746 break;
747 case VpdTool::SKIP_CURRENT:
748 cout << "\nEnter 7 => If you wish to skip the above "
749 "record-keyword pair";
750 break;
751 }
752}
753
Priyanga Ramasamy6d5e7342022-10-14 07:17:25 -0500754void VpdTool::getSystemDataFromCache(IntfPropMap& svpdBusData)
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500755{
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500756 const auto vsys = getAllDBusProperty<GetAllResultType>(
757 constants::pimIntf,
758 "/xyz/openbmc_project/inventory/system/chassis/motherboard",
759 "com.ibm.ipzvpd.VSYS");
760 svpdBusData.emplace("VSYS", vsys);
761
762 const auto vcen = getAllDBusProperty<GetAllResultType>(
763 constants::pimIntf,
764 "/xyz/openbmc_project/inventory/system/chassis/motherboard",
765 "com.ibm.ipzvpd.VCEN");
766 svpdBusData.emplace("VCEN", vcen);
767
768 const auto lxr0 = getAllDBusProperty<GetAllResultType>(
769 constants::pimIntf,
770 "/xyz/openbmc_project/inventory/system/chassis/motherboard",
771 "com.ibm.ipzvpd.LXR0");
772 svpdBusData.emplace("LXR0", lxr0);
773
774 const auto util = getAllDBusProperty<GetAllResultType>(
775 constants::pimIntf,
776 "/xyz/openbmc_project/inventory/system/chassis/motherboard",
777 "com.ibm.ipzvpd.UTIL");
778 svpdBusData.emplace("UTIL", util);
Priyanga Ramasamy6d5e7342022-10-14 07:17:25 -0500779}
780
781int VpdTool::fixSystemVPD()
782{
783 std::string outline(191, '=');
Priyanga Ramasamy24942232023-01-05 04:54:59 -0600784 cout << "\nRestorable record-keyword pairs and their data on backup & "
785 "primary.\n\n"
Priyanga Ramasamy6d5e7342022-10-14 07:17:25 -0500786 << outline << std::endl;
787
788 cout << left << setw(6) << "S.No" << left << setw(8) << "Record" << left
Priyanga Ramasamy24942232023-01-05 04:54:59 -0600789 << setw(9) << "Keyword" << left << setw(75) << "Data On Backup" << left
790 << setw(75) << "Data On Primary" << left << setw(14)
Priyanga Ramasamy6d5e7342022-10-14 07:17:25 -0500791 << "Data Mismatch\n"
792 << outline << std::endl;
793
794 int num = 0;
795
796 // Get system VPD data in map
797 unordered_map<string, DbusPropertyMap> vpdMap;
798 json js;
799 getVPDInMap(constants::systemVpdFilePath, vpdMap, js,
800 constants::pimPath +
801 static_cast<std::string>(constants::SYSTEM_OBJECT));
802
803 // Get system VPD D-Bus Data in a map
804 IntfPropMap svpdBusData;
805 getSystemDataFromCache(svpdBusData);
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500806
807 for (const auto& recordKw : svpdKwdMap)
808 {
809 string record = recordKw.first;
810
811 // Extract specific record data from the svpdBusData map.
812 const auto& rec = svpdBusData.find(record);
813
814 if (rec == svpdBusData.end())
815 {
816 std::cerr << record << " not a part of critical system VPD records."
817 << std::endl;
818 continue;
819 }
820
821 const auto& recData = svpdBusData.find(record)->second;
822
823 string busStr{}, hwValStr{};
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500824
Priyanga Ramasamy952d6c52022-11-07 07:20:24 -0600825 for (const auto& keywordInfo : recordKw.second)
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500826 {
Priyanga Ramasamy952d6c52022-11-07 07:20:24 -0600827 const auto& keyword = get<0>(keywordInfo);
Priyanga Ramasamy6d5e7342022-10-14 07:17:25 -0500828 string mismatch = "NO"; // no mismatch
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500829 string hardwareValue{};
830 auto recItr = vpdMap.find(record);
831
832 if (recItr != vpdMap.end())
833 {
834 DbusPropertyMap& kwValMap = recItr->second;
835 auto kwItr = kwValMap.find(keyword);
836 if (kwItr != kwValMap.end())
837 {
838 hardwareValue = kwItr->second;
839 }
840 }
841
Priyanga Ramasamy6d5e7342022-10-14 07:17:25 -0500842 inventory::Value kwValue;
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500843 for (auto& kwData : recData)
844 {
845 if (kwData.first == keyword)
846 {
847 kwValue = kwData.second;
848 break;
849 }
850 }
851
GiridhariKrishnan63639102023-03-02 05:55:47 -0600852 if (keyword != "SE") // SE to display in Hex string only
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500853 {
854 ostringstream hwValStream;
855 hwValStream << "0x";
856 hwValStr = hwValStream.str();
857
858 for (uint16_t byte : hardwareValue)
859 {
860 hwValStream << setfill('0') << setw(2) << hex << byte;
861 hwValStr = hwValStream.str();
862 }
863
864 if (const auto value = get_if<Binary>(&kwValue))
865 {
GiridhariKrishnan63639102023-03-02 05:55:47 -0600866 busStr = hexString(*value);
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500867 }
868 if (busStr != hwValStr)
869 {
870 mismatch = "YES";
871 }
872 }
873 else
874 {
875 if (const auto value = get_if<Binary>(&kwValue))
876 {
877 busStr = getPrintableValue(*value);
878 }
879 if (busStr != hardwareValue)
880 {
881 mismatch = "YES";
882 }
883 hwValStr = hardwareValue;
884 }
885 recKwData.push_back(
886 make_tuple(++num, record, keyword, busStr, hwValStr, mismatch));
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500887
Priyanga Ramasamy0ac10852022-10-26 05:35:42 -0500888 std::string splitLine(191, '-');
889 cout << left << setw(6) << num << left << setw(8) << record << left
890 << setw(9) << keyword << left << setw(75) << setfill(' ')
891 << busStr << left << setw(75) << setfill(' ') << hwValStr
892 << left << setw(14) << mismatch << '\n'
893 << splitLine << endl;
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500894 }
895 }
896 parseSVPDOptions(js);
897 return 0;
898}
899
900void VpdTool::parseSVPDOptions(const nlohmann::json& json)
901{
902 do
903 {
Priyanga Ramasamy24942232023-01-05 04:54:59 -0600904 printFixSystemVPDOption(VpdTool::BACKUP_DATA_FOR_ALL);
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500905 printFixSystemVPDOption(VpdTool::SYSTEM_BACKPLANE_DATA_FOR_ALL);
906 printFixSystemVPDOption(VpdTool::MORE_OPTIONS);
907 printFixSystemVPDOption(VpdTool::EXIT);
908
909 int option = 0;
910 cin >> option;
Priyanga Ramasamy0ac10852022-10-26 05:35:42 -0500911
912 std::string outline(191, '=');
913 cout << '\n' << outline << endl;
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500914
915 if (json.find("frus") == json.end())
916 {
917 throw runtime_error("Frus not found in json");
918 }
919
920 bool mismatchFound = false;
921
Priyanga Ramasamy24942232023-01-05 04:54:59 -0600922 if (option == VpdTool::BACKUP_DATA_FOR_ALL)
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500923 {
924 for (const auto& data : recKwData)
925 {
926 if (get<5>(data) == "YES")
927 {
928 EditorImpl edit(constants::systemVpdFilePath, json,
929 get<1>(data), get<2>(data));
930 edit.updateKeyword(toBinary(get<3>(data)), 0, true);
931 mismatchFound = true;
932 }
933 }
934
935 if (mismatchFound)
936 {
937 cout << "\nData updated successfully for all mismatching "
938 "record-keyword pairs by choosing their corresponding "
Priyanga Ramasamy24942232023-01-05 04:54:59 -0600939 "data from backup. Exit successfully.\n"
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500940 << endl;
941 }
942 else
943 {
944 cout << "\nNo mismatch found for any of the above mentioned "
945 "record-keyword pair. Exit successfully.\n";
946 }
947
948 exit(0);
949 }
950 else if (option == VpdTool::SYSTEM_BACKPLANE_DATA_FOR_ALL)
951 {
952 for (const auto& data : recKwData)
953 {
954 if (get<5>(data) == "YES")
955 {
956 EditorImpl edit(constants::systemVpdFilePath, json,
957 get<1>(data), get<2>(data));
958 edit.updateKeyword(toBinary(get<4>(data)), 0, true);
959 mismatchFound = true;
960 }
961 }
962
963 if (mismatchFound)
964 {
965 cout << "\nData updated successfully for all mismatching "
966 "record-keyword pairs by choosing their corresponding "
Priyanga Ramasamy24942232023-01-05 04:54:59 -0600967 "data from primary VPD.\n"
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500968 << endl;
969 }
970 else
971 {
972 cout << "\nNo mismatch found for any of the above mentioned "
973 "record-keyword pair. Exit successfully.\n";
974 }
975
976 exit(0);
977 }
978 else if (option == VpdTool::MORE_OPTIONS)
979 {
980 cout << "\nIterate through all restorable record-keyword pairs\n";
981
982 for (const auto& data : recKwData)
983 {
984 do
985 {
Priyanga Ramasamy0ac10852022-10-26 05:35:42 -0500986 cout << '\n' << outline << endl;
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500987
988 cout << left << setw(6) << "S.No" << left << setw(8)
989 << "Record" << left << setw(9) << "Keyword" << left
Priyanga Ramasamy24942232023-01-05 04:54:59 -0600990 << setw(75) << setfill(' ') << "Backup Data" << left
991 << setw(75) << setfill(' ') << "Primary Data" << left
992 << setw(14) << "Data Mismatch" << endl;
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500993
994 cout << left << setw(6) << get<0>(data) << left << setw(8)
995 << get<1>(data) << left << setw(9) << get<2>(data)
Priyanga Ramasamy0ac10852022-10-26 05:35:42 -0500996 << left << setw(75) << setfill(' ') << get<3>(data)
997 << left << setw(75) << setfill(' ') << get<4>(data)
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500998 << left << setw(14) << get<5>(data);
999
Priyanga Ramasamy0ac10852022-10-26 05:35:42 -05001000 cout << '\n' << outline << endl;
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -05001001
1002 if (get<5>(data) == "NO")
1003 {
1004 cout << "\nNo mismatch found.\n";
1005 printFixSystemVPDOption(VpdTool::NEW_VALUE_ON_BOTH);
1006 printFixSystemVPDOption(VpdTool::SKIP_CURRENT);
1007 printFixSystemVPDOption(VpdTool::EXIT);
1008 }
1009 else
1010 {
Priyanga Ramasamy24942232023-01-05 04:54:59 -06001011 printFixSystemVPDOption(
1012 VpdTool::BACKUP_DATA_FOR_CURRENT);
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -05001013 printFixSystemVPDOption(
1014 VpdTool::SYSTEM_BACKPLANE_DATA_FOR_CURRENT);
1015 printFixSystemVPDOption(VpdTool::NEW_VALUE_ON_BOTH);
1016 printFixSystemVPDOption(VpdTool::SKIP_CURRENT);
1017 printFixSystemVPDOption(VpdTool::EXIT);
1018 }
1019
1020 cin >> option;
Priyanga Ramasamy0ac10852022-10-26 05:35:42 -05001021 cout << '\n' << outline << endl;
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -05001022
1023 EditorImpl edit(constants::systemVpdFilePath, json,
1024 get<1>(data), get<2>(data));
1025
Priyanga Ramasamy24942232023-01-05 04:54:59 -06001026 if (option == VpdTool::BACKUP_DATA_FOR_CURRENT)
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -05001027 {
1028 edit.updateKeyword(toBinary(get<3>(data)), 0, true);
1029 cout << "\nData updated successfully.\n";
1030 break;
1031 }
1032 else if (option ==
1033 VpdTool::SYSTEM_BACKPLANE_DATA_FOR_CURRENT)
1034 {
1035 edit.updateKeyword(toBinary(get<4>(data)), 0, true);
1036 cout << "\nData updated successfully.\n";
1037 break;
1038 }
1039 else if (option == VpdTool::NEW_VALUE_ON_BOTH)
1040 {
1041 string value;
Priyanga Ramasamy24942232023-01-05 04:54:59 -06001042 cout << "\nEnter the new value to update on both "
1043 "primary & backup. Value should be in ASCII or "
1044 "in HEX(prefixed with 0x) : ";
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -05001045 cin >> value;
Priyanga Ramasamy0ac10852022-10-26 05:35:42 -05001046 cout << '\n' << outline << endl;
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -05001047
1048 edit.updateKeyword(toBinary(value), 0, true);
1049 cout << "\nData updated successfully.\n";
1050 break;
1051 }
1052 else if (option == VpdTool::SKIP_CURRENT)
1053 {
1054 cout << "\nSkipped the above record-keyword pair. "
1055 "Continue to the next available pair.\n";
1056 break;
1057 }
1058 else if (option == VpdTool::EXIT)
1059 {
1060 cout << "\nExit successfully\n";
1061 exit(0);
1062 }
1063 else
1064 {
1065 cout << "\nProvide a valid option. Retrying for the "
1066 "current record-keyword pair\n";
1067 }
1068 } while (1);
1069 }
1070 exit(0);
1071 }
1072 else if (option == VpdTool::EXIT)
1073 {
1074 cout << "\nExit successfully";
1075 exit(0);
1076 }
1077 else
1078 {
1079 cout << "\nProvide a valid option. Retry.";
1080 continue;
1081 }
1082
1083 } while (true);
Priyanga Ramasamy124ae6c2022-10-18 12:46:14 -05001084}
1085
1086int VpdTool::cleanSystemVPD()
1087{
1088 try
1089 {
1090 // Get system VPD hardware data in map
1091 unordered_map<string, DbusPropertyMap> vpdMap;
1092 json js;
1093 getVPDInMap(constants::systemVpdFilePath, vpdMap, js,
1094 constants::pimPath +
1095 static_cast<std::string>(constants::SYSTEM_OBJECT));
1096
1097 RecKwValMap kwdsToBeUpdated;
1098
1099 for (auto recordMap : svpdKwdMap)
1100 {
1101 const auto& record = recordMap.first;
1102 std::unordered_map<std::string, Binary> kwDefault;
1103 for (auto keywordMap : recordMap.second)
1104 {
1105 // Skip those keywords which cannot be reset at manufacturing
1106 if (!std::get<3>(keywordMap))
1107 {
1108 continue;
1109 }
1110 const auto& keyword = std::get<0>(keywordMap);
1111
1112 // Get hardware value for this keyword from vpdMap
1113 Binary hardwareValue;
1114
1115 auto recItr = vpdMap.find(record);
1116
1117 if (recItr != vpdMap.end())
1118 {
1119 DbusPropertyMap& kwValMap = recItr->second;
1120 auto kwItr = kwValMap.find(keyword);
1121 if (kwItr != kwValMap.end())
1122 {
1123 hardwareValue = toBinary(kwItr->second);
1124 }
1125 }
1126
1127 // compare hardware value with the keyword's default value
1128 auto defaultValue = std::get<1>(keywordMap);
1129 if (hardwareValue != defaultValue)
1130 {
1131 EditorImpl edit(constants::systemVpdFilePath, js, record,
1132 keyword);
1133 edit.updateKeyword(defaultValue, 0, true);
1134 }
1135 }
1136 }
1137
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -06001138 std::cout << "\n The critical keywords from system backplane VPD has "
1139 "been reset successfully."
1140 << std::endl;
Priyanga Ramasamy124ae6c2022-10-18 12:46:14 -05001141 }
1142 catch (const std::exception& e)
1143 {
1144 std::cerr << e.what();
1145 std::cerr
1146 << "\nManufacturing reset on system vpd keywords is unsuccessful";
1147 }
1148 return 0;
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -06001149}