blob: ff0dfadbd91e33f33da3d3f4cf28e6ff2628a6cf [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
Patrick Williamsc78d8872023-05-10 07:50:56 -05007#include <sdbusplus/bus.hpp>
8
PriyangaRamasamycdf943c2020-03-18 02:25:30 +05309#include <cstdlib>
10#include <filesystem>
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +053011#include <iostream>
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +053012#include <variant>
13#include <vector>
14
15using namespace std;
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +053016using namespace openpower::vpd;
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +053017using namespace inventory;
18using namespace openpower::vpd::manager::editor;
PriyangaRamasamycdf943c2020-03-18 02:25:30 +053019namespace fs = std::filesystem;
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +053020using json = nlohmann::json;
21using namespace openpower::vpd::exceptions;
Priyanga Ramasamy38031312021-10-07 16:39:13 -050022using namespace openpower::vpd::parser;
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -050023using namespace openpower::vpd::parser::factory;
24using namespace openpower::vpd::parser::interface;
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +053025
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -060026bool VpdTool::fileToVector(Binary& data)
27{
28 try
29 {
30 std::ifstream file(value, std::ifstream::in);
31
32 if (file)
33 {
34 std::string line;
35 while (std::getline(file, line))
36 {
37 std::istringstream iss(line);
38 std::string byteStr;
39 while (iss >> std::setw(2) >> std::hex >> byteStr)
40 {
41 uint8_t byte = strtoul(byteStr.c_str(), nullptr, 16);
42 data.emplace(data.end(), byte);
43 }
44 }
45 return true;
46 }
47 else
48 {
49 std::cerr << "Unable to open the given file " << value << std::endl;
50 }
51 }
52 catch (std::exception& e)
53 {
54 std::cerr << e.what();
55 }
56 return false;
57}
58
59bool VpdTool::copyStringToFile(const std::string& input)
60{
61 try
62 {
63 std::ofstream outFile(value, std::ofstream::out);
64
65 if (outFile.is_open())
66 {
67 std::string hexString = input;
68 if (input.substr(0, 2) == "0x")
69 {
70 // truncating prefix 0x
71 hexString = input.substr(2);
72 }
73 outFile.write(hexString.c_str(), hexString.length());
74 }
75 else
76 {
77 std::cerr << "Error opening output file " << value << std::endl;
78 return false;
79 }
80
81 outFile.close();
82 }
83 catch (std::exception& e)
84 {
85 std::cerr << e.what();
86 return false;
87 }
88 return true;
89}
90
Priyanga Ramasamy6d5e7342022-10-14 07:17:25 -050091static void
92 getVPDInMap(const std::string& vpdPath,
93 std::unordered_map<std::string, DbusPropertyMap>& vpdMap,
94 json& js, const std::string& invPath)
95{
96 auto jsonToParse = INVENTORY_JSON_DEFAULT;
97 if (fs::exists(INVENTORY_JSON_SYM_LINK))
98 {
99 jsonToParse = INVENTORY_JSON_SYM_LINK;
100 }
101
102 std::ifstream inventoryJson(jsonToParse);
103 if (!inventoryJson)
104 {
105 throw std::runtime_error("VPD JSON file not found");
106 }
107
108 try
109 {
110 js = json::parse(inventoryJson);
111 }
112 catch (const json::parse_error& ex)
113 {
114 throw std::runtime_error("VPD JSON parsing failed");
115 }
116
117 Binary vpdVector{};
118
girik18bb9852022-11-16 05:48:13 -0600119 uint32_t vpdStartOffset = 0;
Priyanga Ramasamy6d5e7342022-10-14 07:17:25 -0500120 vpdVector = getVpdDataInVector(js, constants::systemVpdFilePath);
girik18bb9852022-11-16 05:48:13 -0600121 ParserInterface* parser = ParserFactory::getParser(
122 vpdVector, invPath, constants::systemVpdFilePath, vpdStartOffset);
Priyanga Ramasamy6d5e7342022-10-14 07:17:25 -0500123 auto parseResult = parser->parse();
124 ParserFactory::freeParser(parser);
125
126 if (auto pVal = std::get_if<Store>(&parseResult))
127 {
128 vpdMap = pVal->getVpdMap();
129 }
130 else
131 {
Patrick Williamsc78d8872023-05-10 07:50:56 -0500132 std::string err = vpdPath +
133 " is not of type IPZ VPD. Unable to parse the VPD.";
Priyanga Ramasamy6d5e7342022-10-14 07:17:25 -0500134 throw std::runtime_error(err);
135 }
136}
137
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530138Binary VpdTool::toBinary(const std::string& value)
139{
140 Binary val{};
141 if (value.find("0x") == string::npos)
142 {
143 val.assign(value.begin(), value.end());
144 }
145 else if (value.find("0x") != string::npos)
146 {
147 stringstream ss;
148 ss.str(value.substr(2));
149 string byteStr{};
150
Priyanga Ramasamyec912e62021-12-15 22:47:51 -0600151 if (value.length() % 2 != 0)
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530152 {
Priyanga Ramasamyec912e62021-12-15 22:47:51 -0600153 throw runtime_error(
154 "VPD-TOOL write option accepts 2 digit hex numbers. (Eg. 0x1 "
155 "should be given as 0x01). Aborting the write operation.");
156 }
157
158 if (value.find_first_not_of("0123456789abcdefABCDEF", 2) !=
159 std::string::npos)
160 {
161 throw runtime_error("Provide a valid hexadecimal input.");
162 }
163
164 while (ss >> setw(2) >> byteStr)
165 {
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530166 uint8_t byte = strtoul(byteStr.c_str(), nullptr, 16);
167
168 val.push_back(byte);
169 }
170 }
171
172 else
173 {
174 throw runtime_error("The value to be updated should be either in ascii "
175 "or in hex. Refer --help option");
176 }
177 return val;
178}
PriyangaRamasamycdf943c2020-03-18 02:25:30 +0530179
PriyangaRamasamy6ee637a2021-02-12 04:49:02 -0600180void VpdTool::printReturnCode(int returnCode)
181{
182 if (returnCode)
183 {
184 cout << "\n Command failed with the return code " << returnCode
185 << ". Continuing the execution. " << endl;
186 }
187}
188
PriyangaRamasamycdf943c2020-03-18 02:25:30 +0530189void VpdTool::eraseInventoryPath(string& fru)
190{
191 // Power supply frupath comes with INVENTORY_PATH appended in prefix.
192 // Stripping it off inorder to avoid INVENTORY_PATH duplication
193 // during getVINIProperties() execution.
194 fru.erase(0, sizeof(INVENTORY_PATH) - 1);
195}
196
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530197void VpdTool::debugger(json output)
198{
199 cout << output.dump(4) << '\n';
200}
201
202auto VpdTool::makeDBusCall(const string& objectName, const string& interface,
203 const string& kw)
204{
205 auto bus = sdbusplus::bus::new_default();
206 auto properties =
207 bus.new_method_call(INVENTORY_MANAGER_SERVICE, objectName.c_str(),
208 "org.freedesktop.DBus.Properties", "Get");
209 properties.append(interface);
210 properties.append(kw);
211 auto result = bus.call(properties);
212
213 if (result.is_method_error())
214 {
215 throw runtime_error("Get api failed");
216 }
217 return result;
218}
219
PriyangaRamasamy8cc5b152021-06-03 13:05:17 -0500220json VpdTool::getVINIProperties(string invPath)
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530221{
222 variant<Binary> response;
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530223 json kwVal = json::object({});
224
225 vector<string> keyword{"CC", "SN", "PN", "FN", "DR"};
226 string interface = "com.ibm.ipzvpd.VINI";
PriyangaRamasamycdf943c2020-03-18 02:25:30 +0530227 string objectName = {};
228
229 if (invPath.find(INVENTORY_PATH) != string::npos)
230 {
231 objectName = invPath;
232 eraseInventoryPath(invPath);
233 }
234 else
235 {
236 objectName = INVENTORY_PATH + invPath;
237 }
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530238 for (string kw : keyword)
239 {
240 try
241 {
242 makeDBusCall(objectName, interface, kw).read(response);
243
244 if (auto vec = get_if<Binary>(&response))
245 {
PriyangaRamasamy887a42a2020-09-03 00:33:57 +0530246 string printableVal = getPrintableValue(*vec);
247 kwVal.emplace(kw, printableVal);
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530248 }
249 }
Patrick Williams2eb01762022-07-22 19:26:56 -0500250 catch (const sdbusplus::exception_t& e)
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530251 {
PriyangaRamasamy8cc5b152021-06-03 13:05:17 -0500252 if (string(e.name()) ==
253 string("org.freedesktop.DBus.Error.UnknownObject"))
254 {
255 kwVal.emplace(invPath, json::object({}));
256 objFound = false;
257 break;
258 }
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530259 }
260 }
261
PriyangaRamasamy8cc5b152021-06-03 13:05:17 -0500262 return kwVal;
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530263}
264
PriyangaRamasamy8cc5b152021-06-03 13:05:17 -0500265void VpdTool::getExtraInterfaceProperties(const string& invPath,
266 const string& extraInterface,
267 const json& prop, json& output)
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530268{
269 variant<string> response;
270
271 string objectName = INVENTORY_PATH + invPath;
272
273 for (const auto& itProp : prop.items())
274 {
275 string kw = itProp.key();
276 try
277 {
278 makeDBusCall(objectName, extraInterface, kw).read(response);
279
280 if (auto str = get_if<string>(&response))
281 {
282 output.emplace(kw, *str);
283 }
284 }
Patrick Williams2eb01762022-07-22 19:26:56 -0500285 catch (const sdbusplus::exception_t& e)
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530286 {
PriyangaRamasamy8cc5b152021-06-03 13:05:17 -0500287 if (std::string(e.name()) ==
288 std::string("org.freedesktop.DBus.Error.UnknownObject"))
289 {
290 objFound = false;
291 break;
292 }
293 else if (std::string(e.name()) ==
294 std::string("org.freedesktop.DBus.Error.UnknownProperty"))
295 {
296 output.emplace(kw, "");
297 }
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530298 }
299 }
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530300}
301
302json VpdTool::interfaceDecider(json& itemEEPROM)
303{
304 if (itemEEPROM.find("inventoryPath") == itemEEPROM.end())
305 {
306 throw runtime_error("Inventory Path not found");
307 }
308
309 if (itemEEPROM.find("extraInterfaces") == itemEEPROM.end())
310 {
311 throw runtime_error("Extra Interfaces not found");
312 }
313
PriyangaRamasamy8cc5b152021-06-03 13:05:17 -0500314 json subOutput = json::object({});
Alpana Kumarib6965f12020-06-01 00:32:21 -0500315 fruType = "FRU";
316
PriyangaRamasamy8cc5b152021-06-03 13:05:17 -0500317 json j;
318 objFound = true;
319 string invPath = itemEEPROM.at("inventoryPath");
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530320
PriyangaRamasamy8cc5b152021-06-03 13:05:17 -0500321 j = getVINIProperties(invPath);
322
323 if (objFound)
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530324 {
PriyangaRamasamy8cc5b152021-06-03 13:05:17 -0500325 subOutput.insert(j.begin(), j.end());
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530326 json js;
PriyangaRamasamy8cc5b152021-06-03 13:05:17 -0500327 if (itemEEPROM.find("type") != itemEEPROM.end())
328 {
329 fruType = itemEEPROM.at("type");
330 }
331 js.emplace("TYPE", fruType);
332
333 if (invPath.find("powersupply") != string::npos)
334 {
335 js.emplace("type", POWER_SUPPLY_TYPE_INTERFACE);
336 }
337 else if (invPath.find("fan") != string::npos)
338 {
339 js.emplace("type", FAN_INTERFACE);
340 }
341
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530342 for (const auto& ex : itemEEPROM["extraInterfaces"].items())
343 {
Priyanga Ramasamy051b34f2023-06-28 00:37:43 -0500344 // Properties under Decorator.Asset interface are derived from VINI
345 // keywords. Displaying VINI keywords and skipping Decorator.Asset
346 // interface's properties will avoid duplicate entries in vpd-tool
347 // output.
348 if (ex.key() == "xyz.openbmc_project.Inventory.Decorator.Asset")
349 {
350 continue;
351 }
352
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530353 if (!(ex.value().is_null()))
354 {
Priyanga Ramasamydacaa472021-10-07 12:22:41 -0500355 // TODO: Remove this if condition check once inventory json is
356 // updated with xyz location code interface.
357 if (ex.key() == "com.ibm.ipzvpd.Location")
358 {
359 getExtraInterfaceProperties(
360 invPath,
361 "xyz.openbmc_project.Inventory.Decorator.LocationCode",
362 ex.value(), js);
363 }
364 else
365 {
366 getExtraInterfaceProperties(invPath, ex.key(), ex.value(),
367 js);
368 }
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530369 }
PriyangaRamasamy8cc5b152021-06-03 13:05:17 -0500370 if ((ex.key().find("Item") != string::npos) &&
371 (ex.value().is_null()))
372 {
373 js.emplace("type", ex.key());
374 }
375 subOutput.insert(js.begin(), js.end());
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530376 }
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530377 }
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500378 return subOutput;
379}
380
Priyanga Ramasamyd90aadb2023-03-28 12:25:14 -0500381json VpdTool::getPresentPropJson(const std::string& invPath)
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500382{
383 std::variant<bool> response;
Priyanga Ramasamyd90aadb2023-03-28 12:25:14 -0500384 std::string presence = "Unknown";
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500385
Priyanga Ramasamyd90aadb2023-03-28 12:25:14 -0500386 try
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500387 {
Priyanga Ramasamyd90aadb2023-03-28 12:25:14 -0500388 makeDBusCall(invPath, "xyz.openbmc_project.Inventory.Item", "Present")
389 .read(response);
390
391 if (auto pVal = get_if<bool>(&response))
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500392 {
Priyanga Ramasamyd90aadb2023-03-28 12:25:14 -0500393 presence = *pVal ? "true" : "false";
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500394 }
395 }
Priyanga Ramasamyd90aadb2023-03-28 12:25:14 -0500396 catch (const sdbusplus::exception::SdBusError& e)
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500397 {
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600398 presence = "Unknown";
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500399 }
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600400
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500401 json js;
402 js.emplace("Present", presence);
403 return js;
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530404}
405
406json VpdTool::parseInvJson(const json& jsObject, char flag, string fruPath)
407{
408 json output = json::object({});
409 bool validObject = false;
410
411 if (jsObject.find("frus") == jsObject.end())
412 {
413 throw runtime_error("Frus missing in Inventory json");
414 }
415 else
416 {
417 for (const auto& itemFRUS : jsObject["frus"].items())
418 {
419 for (auto itemEEPROM : itemFRUS.value())
420 {
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500421 json subOutput = json::object({});
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530422 try
423 {
424 if (flag == 'O')
425 {
426 if (itemEEPROM.find("inventoryPath") ==
427 itemEEPROM.end())
428 {
429 throw runtime_error("Inventory Path not found");
430 }
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530431 else if (itemEEPROM.at("inventoryPath") == fruPath)
432 {
433 validObject = true;
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500434 subOutput = interfaceDecider(itemEEPROM);
435 json presentJs = getPresentPropJson(
Priyanga Ramasamyd90aadb2023-03-28 12:25:14 -0500436 "/xyz/openbmc_project/inventory" + fruPath);
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500437 subOutput.insert(presentJs.begin(),
438 presentJs.end());
439 output.emplace(fruPath, subOutput);
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530440 return output;
441 }
442 }
443 else
444 {
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500445 subOutput = interfaceDecider(itemEEPROM);
446 json presentJs = getPresentPropJson(
447 "/xyz/openbmc_project/inventory" +
Priyanga Ramasamyd90aadb2023-03-28 12:25:14 -0500448 string(itemEEPROM.at("inventoryPath")));
Priyanga Ramasamy0086dd12021-09-28 10:31:50 -0500449 subOutput.insert(presentJs.begin(), presentJs.end());
450 output.emplace(string(itemEEPROM.at("inventoryPath")),
451 subOutput);
452 }
453 }
Patrick Williams8e15b932021-10-06 13:04:22 -0500454 catch (const exception& e)
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530455 {
456 cerr << e.what();
457 }
458 }
459 }
460 if ((flag == 'O') && (!validObject))
461 {
462 throw runtime_error(
463 "Invalid object path. Refer --dumpInventory/-i option.");
464 }
465 }
466 return output;
467}
468
469void VpdTool::dumpInventory(const nlohmann::basic_json<>& jsObject)
470{
471 char flag = 'I';
PriyangaRamasamycdf943c2020-03-18 02:25:30 +0530472 json output = json::array({});
473 output.emplace_back(parseInvJson(jsObject, flag, ""));
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530474 debugger(output);
475}
476
477void VpdTool::dumpObject(const nlohmann::basic_json<>& jsObject)
478{
479 char flag = 'O';
PriyangaRamasamycdf943c2020-03-18 02:25:30 +0530480 json output = json::array({});
Santosh Puranikd5d52bb2020-07-28 15:08:10 +0530481 output.emplace_back(parseInvJson(jsObject, flag, fruPath));
PriyangaRamasamy1f0b1e62020-02-20 20:48:25 +0530482 debugger(output);
483}
PriyangaRamasamy02d4d4e2020-02-24 14:54:45 +0530484
485void VpdTool::readKeyword()
486{
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600487 const std::string& kw = getDbusNameForThisKw(keyword);
488
PriyangaRamasamy02d4d4e2020-02-24 14:54:45 +0530489 string interface = "com.ibm.ipzvpd.";
490 variant<Binary> response;
491
492 try
493 {
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600494 makeDBusCall(INVENTORY_PATH + fruPath, interface + recordName, kw)
PriyangaRamasamy02d4d4e2020-02-24 14:54:45 +0530495 .read(response);
496
PriyangaRamasamy887a42a2020-09-03 00:33:57 +0530497 string printableVal{};
PriyangaRamasamy02d4d4e2020-02-24 14:54:45 +0530498 if (auto vec = get_if<Binary>(&response))
499 {
PriyangaRamasamy887a42a2020-09-03 00:33:57 +0530500 printableVal = getPrintableValue(*vec);
PriyangaRamasamy02d4d4e2020-02-24 14:54:45 +0530501 }
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600502
503 if (!value.empty())
504 {
505 if (copyStringToFile(printableVal))
506 {
507 std::cout << "Value read is saved in the file " << value
508 << std::endl;
509 return;
510 }
511 else
512 {
513 std::cerr << "Error while saving the read value in file. "
514 "Displaying the read value on console"
515 << std::endl;
516 }
517 }
518
519 json output = json::object({});
520 json kwVal = json::object({});
PriyangaRamasamy887a42a2020-09-03 00:33:57 +0530521 kwVal.emplace(keyword, printableVal);
PriyangaRamasamy02d4d4e2020-02-24 14:54:45 +0530522
523 output.emplace(fruPath, kwVal);
524
525 debugger(output);
526 }
Patrick Williams8e15b932021-10-06 13:04:22 -0500527 catch (const json::exception& e)
PriyangaRamasamy02d4d4e2020-02-24 14:54:45 +0530528 {
GiridhariKrishnan63639102023-03-02 05:55:47 -0600529 std::cout << "Keyword Value: " << keyword << std::endl;
530 std::cout << e.what() << std::endl;
PriyangaRamasamy02d4d4e2020-02-24 14:54:45 +0530531 }
532}
PriyangaRamasamyd09d2ec2020-03-12 14:11:50 +0530533
534int VpdTool::updateKeyword()
535{
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600536 Binary val;
537
538 if (std::filesystem::exists(value))
539 {
540 if (!fileToVector(val))
541 {
542 std::cout << "Keyword " << keyword << " update failed."
543 << std::endl;
544 return 1;
545 }
546 }
547 else
548 {
549 val = toBinary(value);
550 }
551
PriyangaRamasamyd09d2ec2020-03-12 14:11:50 +0530552 auto bus = sdbusplus::bus::new_default();
Patrick Williamsc78d8872023-05-10 07:50:56 -0500553 auto properties = bus.new_method_call(BUSNAME, OBJPATH, IFACE,
554 "WriteKeyword");
PriyangaRamasamyd09d2ec2020-03-12 14:11:50 +0530555 properties.append(static_cast<sdbusplus::message::object_path>(fruPath));
556 properties.append(recordName);
557 properties.append(keyword);
558 properties.append(val);
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600559
560 // When there is a request to write 10K bytes, there occurs a delay in dbus
561 // call which leads to dbus timeout exception. To avoid such exceptions
562 // increase the timeout period from default 25 seconds to 60 seconds.
563 auto timeoutInMicroSeconds = 60 * 1000000L;
564 auto result = bus.call(properties, timeoutInMicroSeconds);
PriyangaRamasamyd09d2ec2020-03-12 14:11:50 +0530565
566 if (result.is_method_error())
567 {
568 throw runtime_error("Get api failed");
569 }
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600570 std::cout << "Data updated successfully " << std::endl;
PriyangaRamasamyd09d2ec2020-03-12 14:11:50 +0530571 return 0;
572}
PriyangaRamasamy0407b172020-03-31 13:57:18 +0530573
574void VpdTool::forceReset(const nlohmann::basic_json<>& jsObject)
575{
576 for (const auto& itemFRUS : jsObject["frus"].items())
577 {
578 for (const auto& itemEEPROM : itemFRUS.value().items())
579 {
580 string fru = itemEEPROM.value().at("inventoryPath");
581
582 fs::path fruCachePath = INVENTORY_MANAGER_CACHE;
583 fruCachePath += INVENTORY_PATH;
584 fruCachePath += fru;
585
586 try
587 {
588 for (const auto& it : fs::directory_iterator(fruCachePath))
589 {
590 if (fs::is_regular_file(it.status()))
591 {
592 fs::remove(it);
593 }
594 }
595 }
596 catch (const fs::filesystem_error& e)
Patrick Williamsc78d8872023-05-10 07:50:56 -0500597 {}
PriyangaRamasamy0407b172020-03-31 13:57:18 +0530598 }
599 }
600
PriyangaRamasamy6ee637a2021-02-12 04:49:02 -0600601 cout.flush();
PriyangaRamasamy0407b172020-03-31 13:57:18 +0530602 string udevRemove = "udevadm trigger -c remove -s \"*nvmem*\" -v";
PriyangaRamasamy6ee637a2021-02-12 04:49:02 -0600603 int returnCode = system(udevRemove.c_str());
604 printReturnCode(returnCode);
PriyangaRamasamy0407b172020-03-31 13:57:18 +0530605
606 string invManagerRestart =
607 "systemctl restart xyz.openbmc_project.Inventory.Manager.service";
PriyangaRamasamy6ee637a2021-02-12 04:49:02 -0600608 returnCode = system(invManagerRestart.c_str());
609 printReturnCode(returnCode);
PriyangaRamasamy0407b172020-03-31 13:57:18 +0530610
Santosh Puranik6c7a84e2022-03-09 13:42:18 +0530611 string sysVpdRestart = "systemctl restart system-vpd.service";
612 returnCode = system(sysVpdRestart.c_str());
PriyangaRamasamy6ee637a2021-02-12 04:49:02 -0600613 printReturnCode(returnCode);
PriyangaRamasamy0407b172020-03-31 13:57:18 +0530614
615 string udevAdd = "udevadm trigger -c add -s \"*nvmem*\" -v";
PriyangaRamasamy6ee637a2021-02-12 04:49:02 -0600616 returnCode = system(udevAdd.c_str());
617 printReturnCode(returnCode);
PriyangaRamasamy0407b172020-03-31 13:57:18 +0530618}
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530619
Priyanga Ramasamyc99a0b02022-06-08 14:53:39 -0500620int VpdTool::updateHardware(const uint32_t offset)
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530621{
622 int rc = 0;
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600623 Binary val;
624 if (std::filesystem::exists(value))
625 {
626 if (!fileToVector(val))
627 {
628 std::cout << "Keyword " << keyword << " update failed."
629 << std::endl;
630 return 1;
631 }
632 }
633 else
634 {
635 val = toBinary(value);
636 }
637
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530638 ifstream inventoryJson(INVENTORY_JSON_SYM_LINK);
639 try
640 {
641 auto json = nlohmann::json::parse(inventoryJson);
642 EditorImpl edit(fruPath, json, recordName, keyword);
Priyanga Ramasamyc99a0b02022-06-08 14:53:39 -0500643
644 edit.updateKeyword(val, offset, false);
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530645 }
Patrick Williams8e15b932021-10-06 13:04:22 -0500646 catch (const json::parse_error& ex)
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530647 {
648 throw(VpdJsonException("Json Parsing failed", INVENTORY_JSON_SYM_LINK));
649 }
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600650 std::cout << "Data updated successfully " << std::endl;
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530651 return rc;
Priyanga Ramasamy38031312021-10-07 16:39:13 -0500652}
653
Priyanga Ramasamyc99a0b02022-06-08 14:53:39 -0500654void VpdTool::readKwFromHw(const uint32_t& startOffset)
Priyanga Ramasamy38031312021-10-07 16:39:13 -0500655{
Priyanga Ramasamy38031312021-10-07 16:39:13 -0500656 ifstream inventoryJson(INVENTORY_JSON_SYM_LINK);
657 auto jsonFile = nlohmann::json::parse(inventoryJson);
658
Priyanga Ramasamy38031312021-10-07 16:39:13 -0500659 Binary completeVPDFile;
660 completeVPDFile.resize(65504);
661 fstream vpdFileStream;
girikbab2bed2023-05-15 04:00:17 -0500662 std::string inventoryPath;
663
664 if (jsonFile["frus"].contains(fruPath))
665 {
666 uint32_t vpdStartOffset = 0;
667
668 for (const auto& item : jsonFile["frus"][fruPath])
669 {
670 if (item.find("offset") != item.end())
671 {
672 vpdStartOffset = item["offset"];
673 break;
674 }
675 }
676
677 if ((startOffset != vpdStartOffset))
678 {
679 std::cerr << "Invalid offset, please correct the offset" << endl;
680 std::cerr << "Recommended Offset is: " << vpdStartOffset << endl;
681 return;
682 }
683 inventoryPath = jsonFile["frus"][fruPath][0]["inventoryPath"];
684 }
685
Priyanga Ramasamy38031312021-10-07 16:39:13 -0500686 vpdFileStream.open(fruPath,
687 std::ios::in | std::ios::out | std::ios::binary);
688
689 vpdFileStream.seekg(startOffset, ios_base::cur);
690 vpdFileStream.read(reinterpret_cast<char*>(&completeVPDFile[0]), 65504);
691 completeVPDFile.resize(vpdFileStream.gcount());
692 vpdFileStream.clear(std::ios_base::eofbit);
693
694 if (completeVPDFile.empty())
695 {
696 throw std::runtime_error("Invalid File");
697 }
Sunny Srivastavaf31a91b2022-06-09 08:11:29 -0500698
girik18bb9852022-11-16 05:48:13 -0600699 Impl obj(completeVPDFile, (constants::pimPath + inventoryPath), fruPath,
girikbab2bed2023-05-15 04:00:17 -0500700 startOffset);
Priyanga Ramasamy38031312021-10-07 16:39:13 -0500701 std::string keywordVal = obj.readKwFromHw(recordName, keyword);
702
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600703 keywordVal = getPrintableValue(keywordVal);
Priyanga Ramasamy38031312021-10-07 16:39:13 -0500704
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600705 if (keywordVal.empty())
Priyanga Ramasamy38031312021-10-07 16:39:13 -0500706 {
707 std::cerr << "The given keyword " << keyword << " or record "
708 << recordName
709 << " or both are not present in the given FRU path "
710 << fruPath << std::endl;
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600711 return;
Priyanga Ramasamy38031312021-10-07 16:39:13 -0500712 }
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -0600713
714 if (!value.empty())
715 {
716 if (copyStringToFile(keywordVal))
717 {
718 std::cout << "Value read is saved in the file " << value
719 << std::endl;
720 return;
721 }
722 else
723 {
724 std::cerr
725 << "Error while saving the read value in file. Displaying "
726 "the read value on console"
727 << std::endl;
728 }
729 }
730
731 json output = json::object({});
732 json kwVal = json::object({});
733 kwVal.emplace(keyword, keywordVal);
734 output.emplace(fruPath, kwVal);
735 debugger(output);
Priyanga Ramasamy38031312021-10-07 16:39:13 -0500736}
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500737
738void VpdTool::printFixSystemVPDOption(UserOption option)
739{
740 switch (option)
741 {
742 case VpdTool::EXIT:
743 cout << "\nEnter 0 => To exit successfully : ";
744 break;
Priyanga Ramasamy24942232023-01-05 04:54:59 -0600745 case VpdTool::BACKUP_DATA_FOR_ALL:
746 cout << "\n\nEnter 1 => If you choose the data on backup for all "
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500747 "mismatching record-keyword pairs";
748 break;
749 case VpdTool::SYSTEM_BACKPLANE_DATA_FOR_ALL:
Priyanga Ramasamy24942232023-01-05 04:54:59 -0600750 cout << "\nEnter 2 => If you choose the data on primary for all "
751 "mismatching record-keyword pairs";
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500752 break;
753 case VpdTool::MORE_OPTIONS:
754 cout << "\nEnter 3 => If you wish to explore more options";
755 break;
Priyanga Ramasamy24942232023-01-05 04:54:59 -0600756 case VpdTool::BACKUP_DATA_FOR_CURRENT:
757 cout << "\nEnter 4 => If you choose the data on backup as the "
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500758 "right value";
759 break;
760 case VpdTool::SYSTEM_BACKPLANE_DATA_FOR_CURRENT:
Priyanga Ramasamy24942232023-01-05 04:54:59 -0600761 cout << "\nEnter 5 => If you choose the data on primary as the "
762 "right value";
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500763 break;
764 case VpdTool::NEW_VALUE_ON_BOTH:
Priyanga Ramasamy24942232023-01-05 04:54:59 -0600765 cout << "\nEnter 6 => If you wish to enter a new value to update "
766 "both on backup and primary";
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500767 break;
768 case VpdTool::SKIP_CURRENT:
769 cout << "\nEnter 7 => If you wish to skip the above "
770 "record-keyword pair";
771 break;
772 }
773}
774
Priyanga Ramasamy6d5e7342022-10-14 07:17:25 -0500775void VpdTool::getSystemDataFromCache(IntfPropMap& svpdBusData)
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500776{
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500777 const auto vsys = getAllDBusProperty<GetAllResultType>(
778 constants::pimIntf,
779 "/xyz/openbmc_project/inventory/system/chassis/motherboard",
780 "com.ibm.ipzvpd.VSYS");
781 svpdBusData.emplace("VSYS", vsys);
782
783 const auto vcen = getAllDBusProperty<GetAllResultType>(
784 constants::pimIntf,
785 "/xyz/openbmc_project/inventory/system/chassis/motherboard",
786 "com.ibm.ipzvpd.VCEN");
787 svpdBusData.emplace("VCEN", vcen);
788
789 const auto lxr0 = getAllDBusProperty<GetAllResultType>(
790 constants::pimIntf,
791 "/xyz/openbmc_project/inventory/system/chassis/motherboard",
792 "com.ibm.ipzvpd.LXR0");
793 svpdBusData.emplace("LXR0", lxr0);
794
795 const auto util = getAllDBusProperty<GetAllResultType>(
796 constants::pimIntf,
797 "/xyz/openbmc_project/inventory/system/chassis/motherboard",
798 "com.ibm.ipzvpd.UTIL");
799 svpdBusData.emplace("UTIL", util);
Priyanga Ramasamy6d5e7342022-10-14 07:17:25 -0500800}
801
802int VpdTool::fixSystemVPD()
803{
804 std::string outline(191, '=');
Priyanga Ramasamy24942232023-01-05 04:54:59 -0600805 cout << "\nRestorable record-keyword pairs and their data on backup & "
806 "primary.\n\n"
Priyanga Ramasamy6d5e7342022-10-14 07:17:25 -0500807 << outline << std::endl;
808
809 cout << left << setw(6) << "S.No" << left << setw(8) << "Record" << left
Priyanga Ramasamy24942232023-01-05 04:54:59 -0600810 << setw(9) << "Keyword" << left << setw(75) << "Data On Backup" << left
811 << setw(75) << "Data On Primary" << left << setw(14)
Priyanga Ramasamy6d5e7342022-10-14 07:17:25 -0500812 << "Data Mismatch\n"
813 << outline << std::endl;
814
815 int num = 0;
816
817 // Get system VPD data in map
818 unordered_map<string, DbusPropertyMap> vpdMap;
819 json js;
820 getVPDInMap(constants::systemVpdFilePath, vpdMap, js,
821 constants::pimPath +
822 static_cast<std::string>(constants::SYSTEM_OBJECT));
823
824 // Get system VPD D-Bus Data in a map
825 IntfPropMap svpdBusData;
826 getSystemDataFromCache(svpdBusData);
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500827
828 for (const auto& recordKw : svpdKwdMap)
829 {
830 string record = recordKw.first;
831
832 // Extract specific record data from the svpdBusData map.
833 const auto& rec = svpdBusData.find(record);
834
835 if (rec == svpdBusData.end())
836 {
837 std::cerr << record << " not a part of critical system VPD records."
838 << std::endl;
839 continue;
840 }
841
842 const auto& recData = svpdBusData.find(record)->second;
843
844 string busStr{}, hwValStr{};
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500845
Priyanga Ramasamy952d6c52022-11-07 07:20:24 -0600846 for (const auto& keywordInfo : recordKw.second)
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500847 {
Priyanga Ramasamy952d6c52022-11-07 07:20:24 -0600848 const auto& keyword = get<0>(keywordInfo);
Priyanga Ramasamy6d5e7342022-10-14 07:17:25 -0500849 string mismatch = "NO"; // no mismatch
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500850 string hardwareValue{};
851 auto recItr = vpdMap.find(record);
852
853 if (recItr != vpdMap.end())
854 {
855 DbusPropertyMap& kwValMap = recItr->second;
856 auto kwItr = kwValMap.find(keyword);
857 if (kwItr != kwValMap.end())
858 {
859 hardwareValue = kwItr->second;
860 }
861 }
862
Priyanga Ramasamy6d5e7342022-10-14 07:17:25 -0500863 inventory::Value kwValue;
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500864 for (auto& kwData : recData)
865 {
866 if (kwData.first == keyword)
867 {
868 kwValue = kwData.second;
869 break;
870 }
871 }
872
GiridhariKrishnan63639102023-03-02 05:55:47 -0600873 if (keyword != "SE") // SE to display in Hex string only
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500874 {
875 ostringstream hwValStream;
876 hwValStream << "0x";
877 hwValStr = hwValStream.str();
878
879 for (uint16_t byte : hardwareValue)
880 {
881 hwValStream << setfill('0') << setw(2) << hex << byte;
882 hwValStr = hwValStream.str();
883 }
884
885 if (const auto value = get_if<Binary>(&kwValue))
886 {
GiridhariKrishnan63639102023-03-02 05:55:47 -0600887 busStr = hexString(*value);
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500888 }
889 if (busStr != hwValStr)
890 {
891 mismatch = "YES";
892 }
893 }
894 else
895 {
896 if (const auto value = get_if<Binary>(&kwValue))
897 {
898 busStr = getPrintableValue(*value);
899 }
900 if (busStr != hardwareValue)
901 {
902 mismatch = "YES";
903 }
904 hwValStr = hardwareValue;
905 }
906 recKwData.push_back(
907 make_tuple(++num, record, keyword, busStr, hwValStr, mismatch));
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500908
Priyanga Ramasamy0ac10852022-10-26 05:35:42 -0500909 std::string splitLine(191, '-');
910 cout << left << setw(6) << num << left << setw(8) << record << left
911 << setw(9) << keyword << left << setw(75) << setfill(' ')
912 << busStr << left << setw(75) << setfill(' ') << hwValStr
913 << left << setw(14) << mismatch << '\n'
914 << splitLine << endl;
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500915 }
916 }
917 parseSVPDOptions(js);
918 return 0;
919}
920
921void VpdTool::parseSVPDOptions(const nlohmann::json& json)
922{
923 do
924 {
Priyanga Ramasamy24942232023-01-05 04:54:59 -0600925 printFixSystemVPDOption(VpdTool::BACKUP_DATA_FOR_ALL);
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500926 printFixSystemVPDOption(VpdTool::SYSTEM_BACKPLANE_DATA_FOR_ALL);
927 printFixSystemVPDOption(VpdTool::MORE_OPTIONS);
928 printFixSystemVPDOption(VpdTool::EXIT);
929
930 int option = 0;
931 cin >> option;
Priyanga Ramasamy0ac10852022-10-26 05:35:42 -0500932
933 std::string outline(191, '=');
934 cout << '\n' << outline << endl;
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500935
936 if (json.find("frus") == json.end())
937 {
938 throw runtime_error("Frus not found in json");
939 }
940
941 bool mismatchFound = false;
942
Priyanga Ramasamy24942232023-01-05 04:54:59 -0600943 if (option == VpdTool::BACKUP_DATA_FOR_ALL)
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500944 {
945 for (const auto& data : recKwData)
946 {
947 if (get<5>(data) == "YES")
948 {
949 EditorImpl edit(constants::systemVpdFilePath, json,
950 get<1>(data), get<2>(data));
951 edit.updateKeyword(toBinary(get<3>(data)), 0, true);
952 mismatchFound = true;
953 }
954 }
955
956 if (mismatchFound)
957 {
958 cout << "\nData updated successfully for all mismatching "
959 "record-keyword pairs by choosing their corresponding "
Priyanga Ramasamy24942232023-01-05 04:54:59 -0600960 "data from backup. Exit successfully.\n"
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500961 << endl;
962 }
963 else
964 {
965 cout << "\nNo mismatch found for any of the above mentioned "
966 "record-keyword pair. Exit successfully.\n";
967 }
968
969 exit(0);
970 }
971 else if (option == VpdTool::SYSTEM_BACKPLANE_DATA_FOR_ALL)
972 {
973 for (const auto& data : recKwData)
974 {
975 if (get<5>(data) == "YES")
976 {
977 EditorImpl edit(constants::systemVpdFilePath, json,
978 get<1>(data), get<2>(data));
979 edit.updateKeyword(toBinary(get<4>(data)), 0, true);
980 mismatchFound = true;
981 }
982 }
983
984 if (mismatchFound)
985 {
986 cout << "\nData updated successfully for all mismatching "
987 "record-keyword pairs by choosing their corresponding "
Priyanga Ramasamy24942232023-01-05 04:54:59 -0600988 "data from primary VPD.\n"
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -0500989 << endl;
990 }
991 else
992 {
993 cout << "\nNo mismatch found for any of the above mentioned "
994 "record-keyword pair. Exit successfully.\n";
995 }
996
997 exit(0);
998 }
999 else if (option == VpdTool::MORE_OPTIONS)
1000 {
1001 cout << "\nIterate through all restorable record-keyword pairs\n";
1002
1003 for (const auto& data : recKwData)
1004 {
1005 do
1006 {
Priyanga Ramasamy0ac10852022-10-26 05:35:42 -05001007 cout << '\n' << outline << endl;
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -05001008
1009 cout << left << setw(6) << "S.No" << left << setw(8)
1010 << "Record" << left << setw(9) << "Keyword" << left
Priyanga Ramasamy24942232023-01-05 04:54:59 -06001011 << setw(75) << setfill(' ') << "Backup Data" << left
1012 << setw(75) << setfill(' ') << "Primary Data" << left
1013 << setw(14) << "Data Mismatch" << endl;
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -05001014
1015 cout << left << setw(6) << get<0>(data) << left << setw(8)
1016 << get<1>(data) << left << setw(9) << get<2>(data)
Priyanga Ramasamy0ac10852022-10-26 05:35:42 -05001017 << left << setw(75) << setfill(' ') << get<3>(data)
1018 << left << setw(75) << setfill(' ') << get<4>(data)
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -05001019 << left << setw(14) << get<5>(data);
1020
Priyanga Ramasamy0ac10852022-10-26 05:35:42 -05001021 cout << '\n' << outline << endl;
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -05001022
1023 if (get<5>(data) == "NO")
1024 {
1025 cout << "\nNo mismatch found.\n";
1026 printFixSystemVPDOption(VpdTool::NEW_VALUE_ON_BOTH);
1027 printFixSystemVPDOption(VpdTool::SKIP_CURRENT);
1028 printFixSystemVPDOption(VpdTool::EXIT);
1029 }
1030 else
1031 {
Priyanga Ramasamy24942232023-01-05 04:54:59 -06001032 printFixSystemVPDOption(
1033 VpdTool::BACKUP_DATA_FOR_CURRENT);
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -05001034 printFixSystemVPDOption(
1035 VpdTool::SYSTEM_BACKPLANE_DATA_FOR_CURRENT);
1036 printFixSystemVPDOption(VpdTool::NEW_VALUE_ON_BOTH);
1037 printFixSystemVPDOption(VpdTool::SKIP_CURRENT);
1038 printFixSystemVPDOption(VpdTool::EXIT);
1039 }
1040
1041 cin >> option;
Priyanga Ramasamy0ac10852022-10-26 05:35:42 -05001042 cout << '\n' << outline << endl;
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -05001043
1044 EditorImpl edit(constants::systemVpdFilePath, json,
1045 get<1>(data), get<2>(data));
1046
Priyanga Ramasamy24942232023-01-05 04:54:59 -06001047 if (option == VpdTool::BACKUP_DATA_FOR_CURRENT)
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -05001048 {
1049 edit.updateKeyword(toBinary(get<3>(data)), 0, true);
1050 cout << "\nData updated successfully.\n";
1051 break;
1052 }
1053 else if (option ==
1054 VpdTool::SYSTEM_BACKPLANE_DATA_FOR_CURRENT)
1055 {
1056 edit.updateKeyword(toBinary(get<4>(data)), 0, true);
1057 cout << "\nData updated successfully.\n";
1058 break;
1059 }
1060 else if (option == VpdTool::NEW_VALUE_ON_BOTH)
1061 {
1062 string value;
Priyanga Ramasamy24942232023-01-05 04:54:59 -06001063 cout << "\nEnter the new value to update on both "
1064 "primary & backup. Value should be in ASCII or "
1065 "in HEX(prefixed with 0x) : ";
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -05001066 cin >> value;
Priyanga Ramasamy0ac10852022-10-26 05:35:42 -05001067 cout << '\n' << outline << endl;
Priyanga Ramasamy43ffcf72022-06-08 14:10:11 -05001068
1069 edit.updateKeyword(toBinary(value), 0, true);
1070 cout << "\nData updated successfully.\n";
1071 break;
1072 }
1073 else if (option == VpdTool::SKIP_CURRENT)
1074 {
1075 cout << "\nSkipped the above record-keyword pair. "
1076 "Continue to the next available pair.\n";
1077 break;
1078 }
1079 else if (option == VpdTool::EXIT)
1080 {
1081 cout << "\nExit successfully\n";
1082 exit(0);
1083 }
1084 else
1085 {
1086 cout << "\nProvide a valid option. Retrying for the "
1087 "current record-keyword pair\n";
1088 }
1089 } while (1);
1090 }
1091 exit(0);
1092 }
1093 else if (option == VpdTool::EXIT)
1094 {
1095 cout << "\nExit successfully";
1096 exit(0);
1097 }
1098 else
1099 {
1100 cout << "\nProvide a valid option. Retry.";
1101 continue;
1102 }
1103
1104 } while (true);
Priyanga Ramasamy124ae6c2022-10-18 12:46:14 -05001105}
1106
1107int VpdTool::cleanSystemVPD()
1108{
1109 try
1110 {
1111 // Get system VPD hardware data in map
1112 unordered_map<string, DbusPropertyMap> vpdMap;
1113 json js;
1114 getVPDInMap(constants::systemVpdFilePath, vpdMap, js,
1115 constants::pimPath +
1116 static_cast<std::string>(constants::SYSTEM_OBJECT));
1117
1118 RecKwValMap kwdsToBeUpdated;
1119
1120 for (auto recordMap : svpdKwdMap)
1121 {
1122 const auto& record = recordMap.first;
1123 std::unordered_map<std::string, Binary> kwDefault;
1124 for (auto keywordMap : recordMap.second)
1125 {
1126 // Skip those keywords which cannot be reset at manufacturing
1127 if (!std::get<3>(keywordMap))
1128 {
1129 continue;
1130 }
1131 const auto& keyword = std::get<0>(keywordMap);
1132
1133 // Get hardware value for this keyword from vpdMap
1134 Binary hardwareValue;
1135
1136 auto recItr = vpdMap.find(record);
1137
1138 if (recItr != vpdMap.end())
1139 {
1140 DbusPropertyMap& kwValMap = recItr->second;
1141 auto kwItr = kwValMap.find(keyword);
1142 if (kwItr != kwValMap.end())
1143 {
1144 hardwareValue = toBinary(kwItr->second);
1145 }
1146 }
1147
1148 // compare hardware value with the keyword's default value
1149 auto defaultValue = std::get<1>(keywordMap);
1150 if (hardwareValue != defaultValue)
1151 {
1152 EditorImpl edit(constants::systemVpdFilePath, js, record,
1153 keyword);
1154 edit.updateKeyword(defaultValue, 0, true);
1155 }
1156 }
1157 }
1158
Priyanga Ramasamy5629fbc2023-03-01 08:17:19 -06001159 std::cout << "\n The critical keywords from system backplane VPD has "
1160 "been reset successfully."
1161 << std::endl;
Priyanga Ramasamy124ae6c2022-10-18 12:46:14 -05001162 }
1163 catch (const std::exception& e)
1164 {
1165 std::cerr << e.what();
1166 std::cerr
1167 << "\nManufacturing reset on system vpd keywords is unsuccessful";
1168 }
1169 return 0;
Patrick Williamsc78d8872023-05-10 07:50:56 -05001170}