xref: /openbmc/openpower-vpd-parser/vpd-tool/src/vpd_tool.cpp (revision 844f88f984ded76c3b68fab7356a48accb88fec3)
1fa5e4d32SSunny Srivastava #include "config.h"
2fa5e4d32SSunny Srivastava 
3fa5e4d32SSunny Srivastava #include "vpd_tool.hpp"
4fa5e4d32SSunny Srivastava 
5fa5e4d32SSunny Srivastava #include "tool_constants.hpp"
6fa5e4d32SSunny Srivastava #include "tool_types.hpp"
7fa5e4d32SSunny Srivastava #include "tool_utils.hpp"
8fa5e4d32SSunny Srivastava 
9*844f88f9SAnupama B R #include <cstdlib>
10fa5e4d32SSunny Srivastava #include <iostream>
11fa5e4d32SSunny Srivastava #include <regex>
12fa5e4d32SSunny Srivastava #include <tuple>
13fa5e4d32SSunny Srivastava namespace vpd
14fa5e4d32SSunny Srivastava {
readKeyword(const std::string & i_vpdPath,const std::string & i_recordName,const std::string & i_keywordName,const bool i_onHardware,const std::string & i_fileToSave)15fa5e4d32SSunny Srivastava int VpdTool::readKeyword(
16fa5e4d32SSunny Srivastava     const std::string& i_vpdPath, const std::string& i_recordName,
17fa5e4d32SSunny Srivastava     const std::string& i_keywordName, const bool i_onHardware,
18fa5e4d32SSunny Srivastava     const std::string& i_fileToSave)
19fa5e4d32SSunny Srivastava {
20fa5e4d32SSunny Srivastava     int l_rc = constants::FAILURE;
21fa5e4d32SSunny Srivastava     try
22fa5e4d32SSunny Srivastava     {
23fa5e4d32SSunny Srivastava         types::DbusVariantType l_keywordValue;
24fa5e4d32SSunny Srivastava         if (i_onHardware)
25fa5e4d32SSunny Srivastava         {
26fa5e4d32SSunny Srivastava             l_keywordValue = utils::readKeywordFromHardware(
27fa5e4d32SSunny Srivastava                 i_vpdPath, std::make_tuple(i_recordName, i_keywordName));
28fa5e4d32SSunny Srivastava         }
29fa5e4d32SSunny Srivastava         else
30fa5e4d32SSunny Srivastava         {
31fa5e4d32SSunny Srivastava             std::string l_inventoryObjectPath(
32fa5e4d32SSunny Srivastava                 constants::baseInventoryPath + i_vpdPath);
33fa5e4d32SSunny Srivastava 
34fa5e4d32SSunny Srivastava             l_keywordValue = utils::readDbusProperty(
35fa5e4d32SSunny Srivastava                 constants::inventoryManagerService, l_inventoryObjectPath,
36fa5e4d32SSunny Srivastava                 constants::ipzVpdInfPrefix + i_recordName, i_keywordName);
37fa5e4d32SSunny Srivastava         }
38fa5e4d32SSunny Srivastava 
39fa5e4d32SSunny Srivastava         if (const auto l_value =
40fa5e4d32SSunny Srivastava                 std::get_if<types::BinaryVector>(&l_keywordValue);
41fa5e4d32SSunny Srivastava             l_value && !l_value->empty())
42fa5e4d32SSunny Srivastava         {
43fa5e4d32SSunny Srivastava             // ToDo: Print value in both ASCII and hex formats
44fa5e4d32SSunny Srivastava             const std::string& l_keywordStrValue =
45fa5e4d32SSunny Srivastava                 utils::getPrintableValue(*l_value);
46fa5e4d32SSunny Srivastava 
47fa5e4d32SSunny Srivastava             if (i_fileToSave.empty())
48fa5e4d32SSunny Srivastava             {
49fa5e4d32SSunny Srivastava                 utils::displayOnConsole(i_vpdPath, i_keywordName,
50fa5e4d32SSunny Srivastava                                         l_keywordStrValue);
51fa5e4d32SSunny Srivastava                 l_rc = constants::SUCCESS;
52fa5e4d32SSunny Srivastava             }
53fa5e4d32SSunny Srivastava             else
54fa5e4d32SSunny Srivastava             {
55fa5e4d32SSunny Srivastava                 if (utils::saveToFile(i_fileToSave, l_keywordStrValue))
56fa5e4d32SSunny Srivastava                 {
57fa5e4d32SSunny Srivastava                     std::cout
58fa5e4d32SSunny Srivastava                         << "Value read is saved on the file: " << i_fileToSave
59fa5e4d32SSunny Srivastava                         << std::endl;
60fa5e4d32SSunny Srivastava                     l_rc = constants::SUCCESS;
61fa5e4d32SSunny Srivastava                 }
62fa5e4d32SSunny Srivastava                 else
63fa5e4d32SSunny Srivastava                 {
64fa5e4d32SSunny Srivastava                     std::cerr
65fa5e4d32SSunny Srivastava                         << "Error while saving the read value on the file: "
66fa5e4d32SSunny Srivastava                         << i_fileToSave
67fa5e4d32SSunny Srivastava                         << "\nDisplaying the read value on console"
68fa5e4d32SSunny Srivastava                         << std::endl;
69fa5e4d32SSunny Srivastava                     utils::displayOnConsole(i_vpdPath, i_keywordName,
70fa5e4d32SSunny Srivastava                                             l_keywordStrValue);
71fa5e4d32SSunny Srivastava                 }
72fa5e4d32SSunny Srivastava             }
73fa5e4d32SSunny Srivastava         }
74fa5e4d32SSunny Srivastava         else
75fa5e4d32SSunny Srivastava         {
76fa5e4d32SSunny Srivastava             // TODO: Enable logging when verbose is enabled.
77d353990eSAnupama B R             std::cout << "Invalid data type or empty data received."
78d353990eSAnupama B R                       << std::endl;
79fa5e4d32SSunny Srivastava         }
80fa5e4d32SSunny Srivastava     }
81fa5e4d32SSunny Srivastava     catch (const std::exception& l_ex)
82fa5e4d32SSunny Srivastava     {
83fa5e4d32SSunny Srivastava         // TODO: Enable logging when verbose is enabled.
84d353990eSAnupama B R         std::cerr << "Read keyword's value failed for path: " << i_vpdPath
85d353990eSAnupama B R                   << ", Record: " << i_recordName << ", Keyword: "
86d353990eSAnupama B R                   << i_keywordName << ", error: " << l_ex.what() << std::endl;
87fa5e4d32SSunny Srivastava     }
88fa5e4d32SSunny Srivastava     return l_rc;
89fa5e4d32SSunny Srivastava }
90fa5e4d32SSunny Srivastava 
dumpObject(std::string i_fruPath) const91fa5e4d32SSunny Srivastava int VpdTool::dumpObject(std::string i_fruPath) const noexcept
92fa5e4d32SSunny Srivastava {
93fa5e4d32SSunny Srivastava     int l_rc{constants::FAILURE};
94fa5e4d32SSunny Srivastava     try
95fa5e4d32SSunny Srivastava     {
96fa5e4d32SSunny Srivastava         // ToDo: For PFuture system take only full path from the user.
97fa5e4d32SSunny Srivastava         i_fruPath = constants::baseInventoryPath + i_fruPath;
98fa5e4d32SSunny Srivastava 
99fa5e4d32SSunny Srivastava         nlohmann::json l_resultJsonArray = nlohmann::json::array({});
100fa5e4d32SSunny Srivastava         const nlohmann::json l_fruJson = getFruProperties(i_fruPath);
101fa5e4d32SSunny Srivastava         if (!l_fruJson.empty())
102fa5e4d32SSunny Srivastava         {
103fa5e4d32SSunny Srivastava             l_resultJsonArray += l_fruJson;
104fa5e4d32SSunny Srivastava 
105fa5e4d32SSunny Srivastava             utils::printJson(l_resultJsonArray);
106fa5e4d32SSunny Srivastava         }
107fa5e4d32SSunny Srivastava         else
108fa5e4d32SSunny Srivastava         {
109fa5e4d32SSunny Srivastava             std::cout << "FRU [" << i_fruPath
110fa5e4d32SSunny Srivastava                       << "] is not present in the system" << std::endl;
111fa5e4d32SSunny Srivastava         }
112fa5e4d32SSunny Srivastava         l_rc = constants::SUCCESS;
113fa5e4d32SSunny Srivastava     }
114fa5e4d32SSunny Srivastava     catch (std::exception& l_ex)
115fa5e4d32SSunny Srivastava     {
116fa5e4d32SSunny Srivastava         // TODO: Enable logging when verbose is enabled.
117549d0905SSouvik Roy         std::cerr << "Dump Object failed for FRU [" << i_fruPath
118549d0905SSouvik Roy                   << "], Error: " << l_ex.what() << std::endl;
119fa5e4d32SSunny Srivastava     }
120fa5e4d32SSunny Srivastava     return l_rc;
121fa5e4d32SSunny Srivastava }
122fa5e4d32SSunny Srivastava 
123df9e554fSSunny Srivastava template <typename PropertyType>
populateInterfaceJson(const std::string & i_inventoryObjPath,const std::string & i_infName,const std::vector<std::string> & i_propList,nlohmann::json & io_fruJsonObject) const124df9e554fSSunny Srivastava void VpdTool::populateInterfaceJson(const std::string& i_inventoryObjPath,
125df9e554fSSunny Srivastava                                     const std::string& i_infName,
126df9e554fSSunny Srivastava                                     const std::vector<std::string>& i_propList,
127df9e554fSSunny Srivastava                                     nlohmann::json& io_fruJsonObject) const
128df9e554fSSunny Srivastava {
129df9e554fSSunny Srivastava     nlohmann::json l_interfaceJsonObj = nlohmann::json::object({});
130df9e554fSSunny Srivastava 
131df9e554fSSunny Srivastava     auto l_readProperties = [i_inventoryObjPath, &l_interfaceJsonObj, i_infName,
132df9e554fSSunny Srivastava                              this](const std::string& i_property) {
133df9e554fSSunny Srivastava         const nlohmann::json l_propertyJsonObj =
134df9e554fSSunny Srivastava             getInventoryPropertyJson<PropertyType>(i_inventoryObjPath,
135df9e554fSSunny Srivastava                                                    i_infName, i_property);
136df9e554fSSunny Srivastava         l_interfaceJsonObj.insert(l_propertyJsonObj.cbegin(),
137df9e554fSSunny Srivastava                                   l_propertyJsonObj.cend());
138df9e554fSSunny Srivastava     };
139df9e554fSSunny Srivastava 
140df9e554fSSunny Srivastava     std::for_each(i_propList.cbegin(), i_propList.cend(), l_readProperties);
141df9e554fSSunny Srivastava 
142df9e554fSSunny Srivastava     if (!l_interfaceJsonObj.empty())
143df9e554fSSunny Srivastava     {
144df9e554fSSunny Srivastava         io_fruJsonObject.insert(l_interfaceJsonObj.cbegin(),
145df9e554fSSunny Srivastava                                 l_interfaceJsonObj.cend());
146df9e554fSSunny Srivastava     }
147df9e554fSSunny Srivastava }
148df9e554fSSunny Srivastava 
populateFruJson(const std::string & i_inventoryObjPath,nlohmann::json & io_fruJsonObject,const std::vector<std::string> & i_interfaceList) const149df9e554fSSunny Srivastava void VpdTool::populateFruJson(
150df9e554fSSunny Srivastava     const std::string& i_inventoryObjPath, nlohmann::json& io_fruJsonObject,
151df9e554fSSunny Srivastava     const std::vector<std::string>& i_interfaceList) const
152df9e554fSSunny Srivastava {
153df9e554fSSunny Srivastava     for (const auto& l_interface : i_interfaceList)
154df9e554fSSunny Srivastava     {
155df9e554fSSunny Srivastava         if (l_interface == constants::inventoryItemInf)
156df9e554fSSunny Srivastava         {
157df9e554fSSunny Srivastava             const std::vector<std::string> l_properties = {"PrettyName"};
158df9e554fSSunny Srivastava             populateInterfaceJson<std::string>(i_inventoryObjPath,
159df9e554fSSunny Srivastava                                                constants::inventoryItemInf,
160df9e554fSSunny Srivastava                                                l_properties, io_fruJsonObject);
161df9e554fSSunny Srivastava             continue;
162df9e554fSSunny Srivastava         }
163df9e554fSSunny Srivastava 
164df9e554fSSunny Srivastava         if (l_interface == constants::locationCodeInf)
165df9e554fSSunny Srivastava         {
166df9e554fSSunny Srivastava             const std::vector<std::string> l_properties = {"LocationCode"};
167df9e554fSSunny Srivastava             populateInterfaceJson<std::string>(i_inventoryObjPath,
168df9e554fSSunny Srivastava                                                constants::locationCodeInf,
169df9e554fSSunny Srivastava                                                l_properties, io_fruJsonObject);
170df9e554fSSunny Srivastava             continue;
171df9e554fSSunny Srivastava         }
172df9e554fSSunny Srivastava 
173df9e554fSSunny Srivastava         if (l_interface == constants::viniInf)
174df9e554fSSunny Srivastava         {
175df9e554fSSunny Srivastava             const std::vector<std::string> l_properties = {"SN", "PN", "CC",
176df9e554fSSunny Srivastava                                                            "FN", "DR"};
177df9e554fSSunny Srivastava             populateInterfaceJson<vpd::types::BinaryVector>(
178df9e554fSSunny Srivastava                 i_inventoryObjPath, constants::viniInf, l_properties,
179df9e554fSSunny Srivastava                 io_fruJsonObject);
180df9e554fSSunny Srivastava             continue;
181df9e554fSSunny Srivastava         }
182df9e554fSSunny Srivastava 
183df9e554fSSunny Srivastava         if (l_interface == constants::assetInf)
184df9e554fSSunny Srivastava         {
185df9e554fSSunny Srivastava             if (std::find(i_interfaceList.begin(), i_interfaceList.end(),
186df9e554fSSunny Srivastava                           constants::viniInf) != i_interfaceList.end())
187df9e554fSSunny Srivastava             {
188df9e554fSSunny Srivastava                 // The value will be filled from VINI interface. Don't
189df9e554fSSunny Srivastava                 // process asset interface.
190df9e554fSSunny Srivastava                 continue;
191df9e554fSSunny Srivastava             }
192df9e554fSSunny Srivastava 
193df9e554fSSunny Srivastava             const std::vector<std::string> l_properties = {
194df9e554fSSunny Srivastava                 "Model", "SerialNumber", "SubModel"};
195df9e554fSSunny Srivastava 
196df9e554fSSunny Srivastava             populateInterfaceJson<std::string>(i_inventoryObjPath,
197df9e554fSSunny Srivastava                                                constants::assetInf,
198df9e554fSSunny Srivastava                                                l_properties, io_fruJsonObject);
199df9e554fSSunny Srivastava             continue;
200df9e554fSSunny Srivastava         }
201df9e554fSSunny Srivastava 
202df9e554fSSunny Srivastava         if (l_interface == constants::networkInf)
203df9e554fSSunny Srivastava         {
204df9e554fSSunny Srivastava             const std::vector<std::string> l_properties = {"MACAddress"};
205df9e554fSSunny Srivastava             populateInterfaceJson<std::string>(i_inventoryObjPath,
206df9e554fSSunny Srivastava                                                constants::networkInf,
207df9e554fSSunny Srivastava                                                l_properties, io_fruJsonObject);
208df9e554fSSunny Srivastava             continue;
209df9e554fSSunny Srivastava         }
210df9e554fSSunny Srivastava 
211df9e554fSSunny Srivastava         if (l_interface == constants::pcieSlotInf)
212df9e554fSSunny Srivastava         {
213df9e554fSSunny Srivastava             const std::vector<std::string> l_properties = {"SlotType"};
214df9e554fSSunny Srivastava             populateInterfaceJson<std::string>(i_inventoryObjPath,
215df9e554fSSunny Srivastava                                                constants::pcieSlotInf,
216df9e554fSSunny Srivastava                                                l_properties, io_fruJsonObject);
217df9e554fSSunny Srivastava             continue;
218df9e554fSSunny Srivastava         }
219df9e554fSSunny Srivastava 
220df9e554fSSunny Srivastava         if (l_interface == constants::slotNumInf)
221df9e554fSSunny Srivastava         {
222df9e554fSSunny Srivastava             const std::vector<std::string> l_properties = {"SlotNumber"};
223df9e554fSSunny Srivastava             populateInterfaceJson<uint32_t>(i_inventoryObjPath,
224df9e554fSSunny Srivastava                                             constants::slotNumInf, l_properties,
225df9e554fSSunny Srivastava                                             io_fruJsonObject);
226df9e554fSSunny Srivastava             continue;
227df9e554fSSunny Srivastava         }
228df9e554fSSunny Srivastava 
229df9e554fSSunny Srivastava         if (l_interface == constants::i2cDeviceInf)
230df9e554fSSunny Srivastava         {
231df9e554fSSunny Srivastava             const std::vector<std::string> l_properties = {"Address", "Bus"};
232df9e554fSSunny Srivastava             populateInterfaceJson<uint32_t>(i_inventoryObjPath,
233df9e554fSSunny Srivastava                                             constants::i2cDeviceInf,
234df9e554fSSunny Srivastava                                             l_properties, io_fruJsonObject);
235df9e554fSSunny Srivastava             continue;
236df9e554fSSunny Srivastava         }
237df9e554fSSunny Srivastava     }
238df9e554fSSunny Srivastava }
239df9e554fSSunny Srivastava 
getFruProperties(const std::string & i_objectPath) const240fa5e4d32SSunny Srivastava nlohmann::json VpdTool::getFruProperties(const std::string& i_objectPath) const
241fa5e4d32SSunny Srivastava {
242fa5e4d32SSunny Srivastava     // check if FRU is present in the system
243fa5e4d32SSunny Srivastava     if (!isFruPresent(i_objectPath))
244fa5e4d32SSunny Srivastava     {
245fa5e4d32SSunny Srivastava         return nlohmann::json::object_t();
246fa5e4d32SSunny Srivastava     }
247fa5e4d32SSunny Srivastava 
248fa5e4d32SSunny Srivastava     nlohmann::json l_fruJson = nlohmann::json::object_t({});
249fa5e4d32SSunny Srivastava 
250549d0905SSouvik Roy     // need to trim out the base inventory path in the FRU JSON.
251549d0905SSouvik Roy     const std::string l_displayObjectPath =
252549d0905SSouvik Roy         (i_objectPath.find(constants::baseInventoryPath) == std::string::npos)
253549d0905SSouvik Roy             ? i_objectPath
254549d0905SSouvik Roy             : i_objectPath.substr(strlen(constants::baseInventoryPath));
255fa5e4d32SSunny Srivastava 
256549d0905SSouvik Roy     l_fruJson.emplace(l_displayObjectPath, nlohmann::json::object_t({}));
257549d0905SSouvik Roy 
258549d0905SSouvik Roy     auto& l_fruObject = l_fruJson[l_displayObjectPath];
259fa5e4d32SSunny Srivastava 
260df9e554fSSunny Srivastava     types::MapperGetObject l_mapperResp = utils::GetServiceInterfacesForObject(
261df9e554fSSunny Srivastava         i_objectPath, std::vector<std::string>{});
262df9e554fSSunny Srivastava 
263df9e554fSSunny Srivastava     for (const auto& [l_service, l_interfaceList] : l_mapperResp)
264fa5e4d32SSunny Srivastava     {
265df9e554fSSunny Srivastava         if (l_service != constants::inventoryManagerService)
266df9e554fSSunny Srivastava         {
267df9e554fSSunny Srivastava             continue;
268fa5e4d32SSunny Srivastava         }
269df9e554fSSunny Srivastava         populateFruJson(i_objectPath, l_fruObject, l_interfaceList);
270a8bb1663SSouvik Roy     }
271fa5e4d32SSunny Srivastava 
272fa5e4d32SSunny Srivastava     const auto l_typePropertyJson = getFruTypeProperty(i_objectPath);
273fa5e4d32SSunny Srivastava     if (!l_typePropertyJson.empty())
274fa5e4d32SSunny Srivastava     {
275fa5e4d32SSunny Srivastava         l_fruObject.insert(l_typePropertyJson.cbegin(),
276fa5e4d32SSunny Srivastava                            l_typePropertyJson.cend());
277fa5e4d32SSunny Srivastava     }
278fa5e4d32SSunny Srivastava 
279a8bb1663SSouvik Roy     // insert FRU "TYPE"
280a8bb1663SSouvik Roy     l_fruObject.emplace("TYPE", "FRU");
281a8bb1663SSouvik Roy 
282fa5e4d32SSunny Srivastava     return l_fruJson;
283fa5e4d32SSunny Srivastava }
284fa5e4d32SSunny Srivastava 
285fa5e4d32SSunny Srivastava template <typename PropertyType>
getInventoryPropertyJson(const std::string & i_objectPath,const std::string & i_interface,const std::string & i_propertyName) const286fa5e4d32SSunny Srivastava nlohmann::json VpdTool::getInventoryPropertyJson(
287fa5e4d32SSunny Srivastava     const std::string& i_objectPath, const std::string& i_interface,
288fa5e4d32SSunny Srivastava     const std::string& i_propertyName) const noexcept
289fa5e4d32SSunny Srivastava {
290fa5e4d32SSunny Srivastava     nlohmann::json l_resultInJson = nlohmann::json::object({});
291fa5e4d32SSunny Srivastava     try
292fa5e4d32SSunny Srivastava     {
293fa5e4d32SSunny Srivastava         types::DbusVariantType l_keyWordValue;
294fa5e4d32SSunny Srivastava 
295fa5e4d32SSunny Srivastava         l_keyWordValue =
296fa5e4d32SSunny Srivastava             utils::readDbusProperty(constants::inventoryManagerService,
297fa5e4d32SSunny Srivastava                                     i_objectPath, i_interface, i_propertyName);
298fa5e4d32SSunny Srivastava 
299fa5e4d32SSunny Srivastava         if (const auto l_value = std::get_if<PropertyType>(&l_keyWordValue))
300fa5e4d32SSunny Srivastava         {
301fa5e4d32SSunny Srivastava             if constexpr (std::is_same<PropertyType, std::string>::value)
302fa5e4d32SSunny Srivastava             {
303fa5e4d32SSunny Srivastava                 l_resultInJson.emplace(i_propertyName, *l_value);
304fa5e4d32SSunny Srivastava             }
305fa5e4d32SSunny Srivastava             else if constexpr (std::is_same<PropertyType, bool>::value)
306fa5e4d32SSunny Srivastava             {
307fa5e4d32SSunny Srivastava                 l_resultInJson.emplace(i_propertyName,
308fa5e4d32SSunny Srivastava                                        *l_value ? "true" : "false");
309fa5e4d32SSunny Srivastava             }
310fa5e4d32SSunny Srivastava             else if constexpr (std::is_same<PropertyType,
311fa5e4d32SSunny Srivastava                                             types::BinaryVector>::value)
312fa5e4d32SSunny Srivastava             {
313fa5e4d32SSunny Srivastava                 const std::string& l_keywordStrValue =
314fa5e4d32SSunny Srivastava                     vpd::utils::getPrintableValue(*l_value);
315fa5e4d32SSunny Srivastava 
316fa5e4d32SSunny Srivastava                 l_resultInJson.emplace(i_propertyName, l_keywordStrValue);
317fa5e4d32SSunny Srivastava             }
318df9e554fSSunny Srivastava             else if constexpr (std::is_same<PropertyType, uint32_t>::value)
319df9e554fSSunny Srivastava             {
320df9e554fSSunny Srivastava                 l_resultInJson.emplace(i_propertyName,
321df9e554fSSunny Srivastava                                        std::to_string(*l_value));
322df9e554fSSunny Srivastava             }
323fa5e4d32SSunny Srivastava         }
324fa5e4d32SSunny Srivastava         else
325fa5e4d32SSunny Srivastava         {
326fa5e4d32SSunny Srivastava             // TODO: Enable logging when verbose is enabled.
327d353990eSAnupama B R             std::cout << "Invalid data type received." << std::endl;
328fa5e4d32SSunny Srivastava         }
329fa5e4d32SSunny Srivastava     }
330fa5e4d32SSunny Srivastava     catch (const std::exception& l_ex)
331fa5e4d32SSunny Srivastava     {
332fa5e4d32SSunny Srivastava         // TODO: Enable logging when verbose is enabled.
333d353990eSAnupama B R         std::cerr << "Read " << i_propertyName
334d353990eSAnupama B R                   << " value for FRU path: " << i_objectPath
335d353990eSAnupama B R                   << ", failed with exception: " << l_ex.what() << std::endl;
336fa5e4d32SSunny Srivastava     }
337fa5e4d32SSunny Srivastava     return l_resultInJson;
338fa5e4d32SSunny Srivastava }
339fa5e4d32SSunny Srivastava 
fixSystemVpd() const340fa5e4d32SSunny Srivastava int VpdTool::fixSystemVpd() const noexcept
341fa5e4d32SSunny Srivastava {
342fa5e4d32SSunny Srivastava     int l_rc = constants::FAILURE;
343fa5e4d32SSunny Srivastava 
344fa5e4d32SSunny Srivastava     nlohmann::json l_backupRestoreCfgJsonObj = getBackupRestoreCfgJsonObj();
345fa5e4d32SSunny Srivastava     if (!fetchKeywordInfo(l_backupRestoreCfgJsonObj))
346fa5e4d32SSunny Srivastava     {
347fa5e4d32SSunny Srivastava         return l_rc;
348fa5e4d32SSunny Srivastava     }
349fa5e4d32SSunny Srivastava 
350fa5e4d32SSunny Srivastava     printSystemVpd(l_backupRestoreCfgJsonObj);
351fa5e4d32SSunny Srivastava 
352fa5e4d32SSunny Srivastava     do
353fa5e4d32SSunny Srivastava     {
354fa5e4d32SSunny Srivastava         printFixSystemVpdOption(types::UserOption::UseBackupDataForAll);
355fa5e4d32SSunny Srivastava         printFixSystemVpdOption(
356fa5e4d32SSunny Srivastava             types::UserOption::UseSystemBackplaneDataForAll);
357fa5e4d32SSunny Srivastava         printFixSystemVpdOption(types::UserOption::MoreOptions);
358fa5e4d32SSunny Srivastava         printFixSystemVpdOption(types::UserOption::Exit);
359fa5e4d32SSunny Srivastava 
360fa5e4d32SSunny Srivastava         int l_userSelectedOption = types::UserOption::Exit;
361fa5e4d32SSunny Srivastava         std::cin >> l_userSelectedOption;
362fa5e4d32SSunny Srivastava 
363fa5e4d32SSunny Srivastava         std::cout << std::endl << std::string(191, '=') << std::endl;
364fa5e4d32SSunny Srivastava 
365fa5e4d32SSunny Srivastava         if (types::UserOption::UseBackupDataForAll == l_userSelectedOption)
366fa5e4d32SSunny Srivastava         {
367fa5e4d32SSunny Srivastava             l_rc = updateAllKeywords(l_backupRestoreCfgJsonObj, true);
368fa5e4d32SSunny Srivastava             break;
369fa5e4d32SSunny Srivastava         }
370fa5e4d32SSunny Srivastava         else if (types::UserOption::UseSystemBackplaneDataForAll ==
371fa5e4d32SSunny Srivastava                  l_userSelectedOption)
372fa5e4d32SSunny Srivastava         {
373fa5e4d32SSunny Srivastava             l_rc = updateAllKeywords(l_backupRestoreCfgJsonObj, false);
374fa5e4d32SSunny Srivastava             break;
375fa5e4d32SSunny Srivastava         }
376fa5e4d32SSunny Srivastava         else if (types::UserOption::MoreOptions == l_userSelectedOption)
377fa5e4d32SSunny Srivastava         {
378fa5e4d32SSunny Srivastava             l_rc = handleMoreOption(l_backupRestoreCfgJsonObj);
379fa5e4d32SSunny Srivastava             break;
380fa5e4d32SSunny Srivastava         }
381fa5e4d32SSunny Srivastava         else if (types::UserOption::Exit == l_userSelectedOption)
382fa5e4d32SSunny Srivastava         {
383fa5e4d32SSunny Srivastava             std::cout << "Exit successfully" << std::endl;
384fa5e4d32SSunny Srivastava             break;
385fa5e4d32SSunny Srivastava         }
386fa5e4d32SSunny Srivastava         else
387fa5e4d32SSunny Srivastava         {
388fa5e4d32SSunny Srivastava             std::cout << "Provide a valid option. Retry." << std::endl;
389fa5e4d32SSunny Srivastava         }
390fa5e4d32SSunny Srivastava     } while (true);
391fa5e4d32SSunny Srivastava 
392fa5e4d32SSunny Srivastava     return l_rc;
393fa5e4d32SSunny Srivastava }
394fa5e4d32SSunny Srivastava 
writeKeyword(std::string i_vpdPath,const std::string & i_recordName,const std::string & i_keywordName,const std::string & i_keywordValue,const bool i_onHardware)395fa5e4d32SSunny Srivastava int VpdTool::writeKeyword(
396fa5e4d32SSunny Srivastava     std::string i_vpdPath, const std::string& i_recordName,
397fa5e4d32SSunny Srivastava     const std::string& i_keywordName, const std::string& i_keywordValue,
398fa5e4d32SSunny Srivastava     const bool i_onHardware) noexcept
399fa5e4d32SSunny Srivastava {
400fa5e4d32SSunny Srivastava     int l_rc = constants::FAILURE;
401fa5e4d32SSunny Srivastava     try
402fa5e4d32SSunny Srivastava     {
403fa5e4d32SSunny Srivastava         if (i_vpdPath.empty() || i_recordName.empty() ||
404fa5e4d32SSunny Srivastava             i_keywordName.empty() || i_keywordValue.empty())
405fa5e4d32SSunny Srivastava         {
406fa5e4d32SSunny Srivastava             throw std::runtime_error("Received input is empty.");
407fa5e4d32SSunny Srivastava         }
408fa5e4d32SSunny Srivastava 
409fa5e4d32SSunny Srivastava         auto l_paramsToWrite =
410fa5e4d32SSunny Srivastava             std::make_tuple(i_recordName, i_keywordName,
411fa5e4d32SSunny Srivastava                             utils::convertToBinary(i_keywordValue));
412fa5e4d32SSunny Srivastava 
413fa5e4d32SSunny Srivastava         if (i_onHardware)
414fa5e4d32SSunny Srivastava         {
415fa5e4d32SSunny Srivastava             l_rc = utils::writeKeywordOnHardware(i_vpdPath, l_paramsToWrite);
416fa5e4d32SSunny Srivastava         }
417fa5e4d32SSunny Srivastava         else
418fa5e4d32SSunny Srivastava         {
419fa5e4d32SSunny Srivastava             i_vpdPath = constants::baseInventoryPath + i_vpdPath;
420fa5e4d32SSunny Srivastava             l_rc = utils::writeKeyword(i_vpdPath, l_paramsToWrite);
421fa5e4d32SSunny Srivastava         }
422fa5e4d32SSunny Srivastava 
423fa5e4d32SSunny Srivastava         if (l_rc > 0)
424fa5e4d32SSunny Srivastava         {
425fa5e4d32SSunny Srivastava             std::cout << "Data updated successfully " << std::endl;
426fa5e4d32SSunny Srivastava             l_rc = constants::SUCCESS;
427fa5e4d32SSunny Srivastava         }
428fa5e4d32SSunny Srivastava     }
429fa5e4d32SSunny Srivastava     catch (const std::exception& l_ex)
430fa5e4d32SSunny Srivastava     {
431fa5e4d32SSunny Srivastava         // TODO: Enable log when verbose is enabled.
432fa5e4d32SSunny Srivastava         std::cerr << "Write keyword's value for path: " << i_vpdPath
433fa5e4d32SSunny Srivastava                   << ", Record: " << i_recordName
434fa5e4d32SSunny Srivastava                   << ", Keyword: " << i_keywordName
435fa5e4d32SSunny Srivastava                   << " is failed. Exception: " << l_ex.what() << std::endl;
436fa5e4d32SSunny Srivastava     }
437fa5e4d32SSunny Srivastava     return l_rc;
438fa5e4d32SSunny Srivastava }
439fa5e4d32SSunny Srivastava 
getBackupRestoreCfgJsonObj() const440fa5e4d32SSunny Srivastava nlohmann::json VpdTool::getBackupRestoreCfgJsonObj() const noexcept
441fa5e4d32SSunny Srivastava {
442fa5e4d32SSunny Srivastava     nlohmann::json l_parsedBackupRestoreJson{};
443fa5e4d32SSunny Srivastava     try
444fa5e4d32SSunny Srivastava     {
445fa5e4d32SSunny Srivastava         nlohmann::json l_parsedSystemJson =
446fa5e4d32SSunny Srivastava             utils::getParsedJson(INVENTORY_JSON_SYM_LINK);
447fa5e4d32SSunny Srivastava 
448fa5e4d32SSunny Srivastava         // check for mandatory fields at this point itself.
449fa5e4d32SSunny Srivastava         if (!l_parsedSystemJson.contains("backupRestoreConfigPath"))
450fa5e4d32SSunny Srivastava         {
451fa5e4d32SSunny Srivastava             throw std::runtime_error(
452fa5e4d32SSunny Srivastava                 "backupRestoreConfigPath tag is missing from system config JSON : " +
453fa5e4d32SSunny Srivastava                 std::string(INVENTORY_JSON_SYM_LINK));
454fa5e4d32SSunny Srivastava         }
455fa5e4d32SSunny Srivastava 
456fa5e4d32SSunny Srivastava         l_parsedBackupRestoreJson =
457fa5e4d32SSunny Srivastava             utils::getParsedJson(l_parsedSystemJson["backupRestoreConfigPath"]);
458fa5e4d32SSunny Srivastava     }
459fa5e4d32SSunny Srivastava     catch (const std::exception& l_ex)
460fa5e4d32SSunny Srivastava     {
461fa5e4d32SSunny Srivastava         // TODO: Enable logging when verbose is enabled.
462fa5e4d32SSunny Srivastava         std::cerr << l_ex.what() << std::endl;
463fa5e4d32SSunny Srivastava     }
464fa5e4d32SSunny Srivastava 
465fa5e4d32SSunny Srivastava     return l_parsedBackupRestoreJson;
466fa5e4d32SSunny Srivastava }
467fa5e4d32SSunny Srivastava 
cleanSystemVpd(bool i_syncBiosAttributesRequired) const4687f749a6fSSouvik Roy int VpdTool::cleanSystemVpd(bool i_syncBiosAttributesRequired) const noexcept
469fa5e4d32SSunny Srivastava {
470fa5e4d32SSunny Srivastava     try
471fa5e4d32SSunny Srivastava     {
4727f749a6fSSouvik Roy         // In order to do syncBiosAttributes, we need BIOS Config Manager
4737f749a6fSSouvik Roy         // service up and running
4747f749a6fSSouvik Roy         if (i_syncBiosAttributesRequired &&
4757f749a6fSSouvik Roy             !utils::isServiceRunning(constants::biosConfigMgrService))
4767f749a6fSSouvik Roy         {
4777f749a6fSSouvik Roy             std::cerr
4787f749a6fSSouvik Roy                 << "Cannot sync BIOS attributes as BIOS Config Manager service is not running."
4797f749a6fSSouvik Roy                 << std::endl;
4807f749a6fSSouvik Roy             return constants::FAILURE;
4817f749a6fSSouvik Roy         }
48263089420SSouvik Roy 
483fa5e4d32SSunny Srivastava         // get the keyword map from backup_restore json
484fa5e4d32SSunny Srivastava         // iterate through the keyword map get default value of
485fa5e4d32SSunny Srivastava         // l_keywordName.
486fa5e4d32SSunny Srivastava         // use writeKeyword API to update default value on hardware,
487fa5e4d32SSunny Srivastava         // backup and D - Bus.
488fa5e4d32SSunny Srivastava         const nlohmann::json l_parsedBackupRestoreJson =
489fa5e4d32SSunny Srivastava             getBackupRestoreCfgJsonObj();
490fa5e4d32SSunny Srivastava 
491fa5e4d32SSunny Srivastava         // check for mandatory tags
492fa5e4d32SSunny Srivastava         if (l_parsedBackupRestoreJson.contains("source") &&
493fa5e4d32SSunny Srivastava             l_parsedBackupRestoreJson.contains("backupMap") &&
494fa5e4d32SSunny Srivastava             l_parsedBackupRestoreJson["source"].contains("hardwarePath") &&
495fa5e4d32SSunny Srivastava             l_parsedBackupRestoreJson["backupMap"].is_array())
496fa5e4d32SSunny Srivastava         {
497fa5e4d32SSunny Srivastava             // get the source hardware path
498fa5e4d32SSunny Srivastava             const auto& l_hardwarePath =
499fa5e4d32SSunny Srivastava                 l_parsedBackupRestoreJson["source"]["hardwarePath"];
500fa5e4d32SSunny Srivastava 
501fa5e4d32SSunny Srivastava             // iterate through the backup map
502fa5e4d32SSunny Srivastava             for (const auto& l_aRecordKwInfo :
503fa5e4d32SSunny Srivastava                  l_parsedBackupRestoreJson["backupMap"])
504fa5e4d32SSunny Srivastava             {
505fa5e4d32SSunny Srivastava                 // check if Manufacturing Reset is required for this entry
506fa5e4d32SSunny Srivastava                 const bool l_isMfgCleanRequired =
507fa5e4d32SSunny Srivastava                     l_aRecordKwInfo.value("isManufactureResetRequired", false);
508fa5e4d32SSunny Srivastava 
509fa5e4d32SSunny Srivastava                 if (l_isMfgCleanRequired)
510fa5e4d32SSunny Srivastava                 {
511fa5e4d32SSunny Srivastava                     // get the Record name and Keyword name
512fa5e4d32SSunny Srivastava                     const std::string& l_srcRecordName =
513fa5e4d32SSunny Srivastava                         l_aRecordKwInfo.value("sourceRecord", "");
514fa5e4d32SSunny Srivastava                     const std::string& l_srcKeywordName =
515fa5e4d32SSunny Srivastava                         l_aRecordKwInfo.value("sourceKeyword", "");
516fa5e4d32SSunny Srivastava 
517fa5e4d32SSunny Srivastava                     // validate the Record name, Keyword name and the
518fa5e4d32SSunny Srivastava                     // defaultValue
519fa5e4d32SSunny Srivastava                     if (!l_srcRecordName.empty() && !l_srcKeywordName.empty() &&
520fa5e4d32SSunny Srivastava                         l_aRecordKwInfo.contains("defaultValue") &&
521fa5e4d32SSunny Srivastava                         l_aRecordKwInfo["defaultValue"].is_array())
522fa5e4d32SSunny Srivastava                     {
5237f749a6fSSouvik Roy                         // check if this keyword is used for backing up BIOS
5247f749a6fSSouvik Roy                         // attribute
5257f749a6fSSouvik Roy                         const bool l_isUsedForBiosAttributeBackup =
5267f749a6fSSouvik Roy                             l_aRecordKwInfo.value("isBiosSyncRequired", false);
5277f749a6fSSouvik Roy 
5287f749a6fSSouvik Roy                         const types::BinaryVector l_keywordValueToUpdate =
5297f749a6fSSouvik Roy                             (i_syncBiosAttributesRequired &&
5307f749a6fSSouvik Roy                              l_isUsedForBiosAttributeBackup)
5317f749a6fSSouvik Roy                                 ? getVpdValueInBiosConfigManager(
5327f749a6fSSouvik Roy                                       l_srcRecordName, l_srcKeywordName)
5337f749a6fSSouvik Roy                                 : l_aRecordKwInfo["defaultValue"]
534fa5e4d32SSunny Srivastava                                       .get<types::BinaryVector>();
535fa5e4d32SSunny Srivastava 
5367f749a6fSSouvik Roy                         if (l_keywordValueToUpdate.empty())
5377f749a6fSSouvik Roy                         {
5387f749a6fSSouvik Roy                             std::cerr << "Failed to update " << l_srcRecordName
5397f749a6fSSouvik Roy                                       << ":" << l_srcKeywordName
5407f749a6fSSouvik Roy                                       << " . Keyword value to update is empty"
5417f749a6fSSouvik Roy                                       << std::endl;
5427f749a6fSSouvik Roy                             continue;
5437f749a6fSSouvik Roy                         }
5447f749a6fSSouvik Roy 
545fa5e4d32SSunny Srivastava                         // update the Keyword with default value, use D-Bus
546fa5e4d32SSunny Srivastava                         // method UpdateKeyword exposed by vpd-manager.
547fa5e4d32SSunny Srivastava                         // Note: writing to all paths (Primary EEPROM path,
548fa5e4d32SSunny Srivastava                         // Secondary EEPROM path, D-Bus cache and Backup path)
549fa5e4d32SSunny Srivastava                         // is the responsibility of vpd-manager's UpdateKeyword
550fa5e4d32SSunny Srivastava                         // API
551fa5e4d32SSunny Srivastava                         if (constants::FAILURE ==
552fa5e4d32SSunny Srivastava                             utils::writeKeyword(
553fa5e4d32SSunny Srivastava                                 l_hardwarePath,
554fa5e4d32SSunny Srivastava                                 std::make_tuple(l_srcRecordName,
555fa5e4d32SSunny Srivastava                                                 l_srcKeywordName,
5567f749a6fSSouvik Roy                                                 l_keywordValueToUpdate)))
557fa5e4d32SSunny Srivastava                         {
558fa5e4d32SSunny Srivastava                             // TODO: Enable logging when verbose
559fa5e4d32SSunny Srivastava                             // is enabled.
560fa5e4d32SSunny Srivastava                             std::cerr << "Failed to update " << l_srcRecordName
561fa5e4d32SSunny Srivastava                                       << ":" << l_srcKeywordName << std::endl;
562fa5e4d32SSunny Srivastava                         }
563fa5e4d32SSunny Srivastava                     }
564fa5e4d32SSunny Srivastava                     else
565fa5e4d32SSunny Srivastava                     {
566fa5e4d32SSunny Srivastava                         std::cerr
567fa5e4d32SSunny Srivastava                             << "Unrecognized Entry Record [" << l_srcRecordName
568fa5e4d32SSunny Srivastava                             << "] Keyword [" << l_srcKeywordName
569fa5e4d32SSunny Srivastava                             << "] in Backup Restore JSON backup map"
570fa5e4d32SSunny Srivastava                             << std::endl;
571fa5e4d32SSunny Srivastava                     }
572fa5e4d32SSunny Srivastava                 } // mfgClean required check
573fa5e4d32SSunny Srivastava             } // keyword list loop
574fa5e4d32SSunny Srivastava         }
575fa5e4d32SSunny Srivastava         else // backupRestoreJson is not valid
576fa5e4d32SSunny Srivastava         {
577fa5e4d32SSunny Srivastava             std::cerr << "Backup Restore JSON is not valid" << std::endl;
578fa5e4d32SSunny Srivastava         }
579fa5e4d32SSunny Srivastava 
580fa5e4d32SSunny Srivastava         // success/failure message
581fa5e4d32SSunny Srivastava         std::cout << "The critical keywords from system backplane VPD has "
582fa5e4d32SSunny Srivastava                      "been reset successfully."
583fa5e4d32SSunny Srivastava                   << std::endl;
584fa5e4d32SSunny Srivastava 
585fa5e4d32SSunny Srivastava     } // try block end
586fa5e4d32SSunny Srivastava     catch (const std::exception& l_ex)
587fa5e4d32SSunny Srivastava     {
588fa5e4d32SSunny Srivastava         // TODO: Enable logging when verbose is enabled.
589fa5e4d32SSunny Srivastava         std::cerr
590fa5e4d32SSunny Srivastava             << "Manufacturing reset on system vpd keywords is unsuccessful. Error : "
591fa5e4d32SSunny Srivastava             << l_ex.what() << std::endl;
592fa5e4d32SSunny Srivastava     }
593fa5e4d32SSunny Srivastava     return constants::SUCCESS;
594fa5e4d32SSunny Srivastava }
595fa5e4d32SSunny Srivastava 
fetchKeywordInfo(nlohmann::json & io_parsedJsonObj) const596fa5e4d32SSunny Srivastava bool VpdTool::fetchKeywordInfo(nlohmann::json& io_parsedJsonObj) const noexcept
597fa5e4d32SSunny Srivastava {
598fa5e4d32SSunny Srivastava     bool l_returnValue = false;
599fa5e4d32SSunny Srivastava     try
600fa5e4d32SSunny Srivastava     {
601fa5e4d32SSunny Srivastava         if (io_parsedJsonObj.empty() || !io_parsedJsonObj.contains("source") ||
602fa5e4d32SSunny Srivastava             !io_parsedJsonObj.contains("destination") ||
603fa5e4d32SSunny Srivastava             !io_parsedJsonObj.contains("backupMap"))
604fa5e4d32SSunny Srivastava         {
605fa5e4d32SSunny Srivastava             throw std::runtime_error("Invalid JSON");
606fa5e4d32SSunny Srivastava         }
607fa5e4d32SSunny Srivastava 
608fa5e4d32SSunny Srivastava         std::string l_srcVpdPath;
609fa5e4d32SSunny Srivastava         std::string l_dstVpdPath;
610fa5e4d32SSunny Srivastava 
611fa5e4d32SSunny Srivastava         bool l_isSourceOnHardware = false;
612fa5e4d32SSunny Srivastava         if (l_srcVpdPath = io_parsedJsonObj["source"].value("hardwarePath", "");
613fa5e4d32SSunny Srivastava             !l_srcVpdPath.empty())
614fa5e4d32SSunny Srivastava         {
615fa5e4d32SSunny Srivastava             l_isSourceOnHardware = true;
616fa5e4d32SSunny Srivastava         }
617fa5e4d32SSunny Srivastava         else if (l_srcVpdPath =
618fa5e4d32SSunny Srivastava                      io_parsedJsonObj["source"].value("inventoryPath", "");
619fa5e4d32SSunny Srivastava                  l_srcVpdPath.empty())
620fa5e4d32SSunny Srivastava         {
621fa5e4d32SSunny Srivastava             throw std::runtime_error("Source path is empty in JSON");
622fa5e4d32SSunny Srivastava         }
623fa5e4d32SSunny Srivastava 
624fa5e4d32SSunny Srivastava         bool l_isDestinationOnHardware = false;
625fa5e4d32SSunny Srivastava         if (l_dstVpdPath =
626fa5e4d32SSunny Srivastava                 io_parsedJsonObj["destination"].value("hardwarePath", "");
627fa5e4d32SSunny Srivastava             !l_dstVpdPath.empty())
628fa5e4d32SSunny Srivastava         {
629fa5e4d32SSunny Srivastava             l_isDestinationOnHardware = true;
630fa5e4d32SSunny Srivastava         }
631fa5e4d32SSunny Srivastava         else if (l_dstVpdPath =
632fa5e4d32SSunny Srivastava                      io_parsedJsonObj["destination"].value("inventoryPath", "");
633fa5e4d32SSunny Srivastava                  l_dstVpdPath.empty())
634fa5e4d32SSunny Srivastava         {
635fa5e4d32SSunny Srivastava             throw std::runtime_error("Destination path is empty in JSON");
636fa5e4d32SSunny Srivastava         }
637fa5e4d32SSunny Srivastava 
638fa5e4d32SSunny Srivastava         for (auto& l_aRecordKwInfo : io_parsedJsonObj["backupMap"])
639fa5e4d32SSunny Srivastava         {
640fa5e4d32SSunny Srivastava             const std::string& l_srcRecordName =
641fa5e4d32SSunny Srivastava                 l_aRecordKwInfo.value("sourceRecord", "");
642fa5e4d32SSunny Srivastava             const std::string& l_srcKeywordName =
643fa5e4d32SSunny Srivastava                 l_aRecordKwInfo.value("sourceKeyword", "");
644fa5e4d32SSunny Srivastava             const std::string& l_dstRecordName =
645fa5e4d32SSunny Srivastava                 l_aRecordKwInfo.value("destinationRecord", "");
646fa5e4d32SSunny Srivastava             const std::string& l_dstKeywordName =
647fa5e4d32SSunny Srivastava                 l_aRecordKwInfo.value("destinationKeyword", "");
648fa5e4d32SSunny Srivastava 
649fa5e4d32SSunny Srivastava             if (l_srcRecordName.empty() || l_dstRecordName.empty() ||
650fa5e4d32SSunny Srivastava                 l_srcKeywordName.empty() || l_dstKeywordName.empty())
651fa5e4d32SSunny Srivastava             {
652fa5e4d32SSunny Srivastava                 // TODO: Enable logging when verbose is enabled.
653fa5e4d32SSunny Srivastava                 std::cout << "Record or keyword not found in the JSON."
654fa5e4d32SSunny Srivastava                           << std::endl;
655fa5e4d32SSunny Srivastava                 continue;
656fa5e4d32SSunny Srivastava             }
657fa5e4d32SSunny Srivastava 
658fa5e4d32SSunny Srivastava             types::DbusVariantType l_srcKeywordVariant;
659fa5e4d32SSunny Srivastava             if (l_isSourceOnHardware)
660fa5e4d32SSunny Srivastava             {
661fa5e4d32SSunny Srivastava                 l_srcKeywordVariant = utils::readKeywordFromHardware(
662fa5e4d32SSunny Srivastava                     l_srcVpdPath,
663fa5e4d32SSunny Srivastava                     std::make_tuple(l_srcRecordName, l_srcKeywordName));
664fa5e4d32SSunny Srivastava             }
665fa5e4d32SSunny Srivastava             else
666fa5e4d32SSunny Srivastava             {
667fa5e4d32SSunny Srivastava                 l_srcKeywordVariant = utils::readDbusProperty(
668fa5e4d32SSunny Srivastava                     constants::inventoryManagerService, l_srcVpdPath,
669fa5e4d32SSunny Srivastava                     constants::ipzVpdInfPrefix + l_srcRecordName,
670fa5e4d32SSunny Srivastava                     l_srcKeywordName);
671fa5e4d32SSunny Srivastava             }
672fa5e4d32SSunny Srivastava 
673fa5e4d32SSunny Srivastava             if (auto l_srcKeywordValue =
674fa5e4d32SSunny Srivastava                     std::get_if<types::BinaryVector>(&l_srcKeywordVariant);
675fa5e4d32SSunny Srivastava                 l_srcKeywordValue && !l_srcKeywordValue->empty())
676fa5e4d32SSunny Srivastava             {
677fa5e4d32SSunny Srivastava                 l_aRecordKwInfo["sourcekeywordValue"] = *l_srcKeywordValue;
678fa5e4d32SSunny Srivastava             }
679fa5e4d32SSunny Srivastava             else
680fa5e4d32SSunny Srivastava             {
681fa5e4d32SSunny Srivastava                 // TODO: Enable logging when verbose is enabled.
682fa5e4d32SSunny Srivastava                 std::cout
683fa5e4d32SSunny Srivastava                     << "Invalid data type or empty data received, for source record: "
684fa5e4d32SSunny Srivastava                     << l_srcRecordName << ", keyword: " << l_srcKeywordName
685fa5e4d32SSunny Srivastava                     << std::endl;
686fa5e4d32SSunny Srivastava                 continue;
687fa5e4d32SSunny Srivastava             }
688fa5e4d32SSunny Srivastava 
689fa5e4d32SSunny Srivastava             types::DbusVariantType l_dstKeywordVariant;
690fa5e4d32SSunny Srivastava             if (l_isDestinationOnHardware)
691fa5e4d32SSunny Srivastava             {
692fa5e4d32SSunny Srivastava                 l_dstKeywordVariant = utils::readKeywordFromHardware(
693fa5e4d32SSunny Srivastava                     l_dstVpdPath,
694fa5e4d32SSunny Srivastava                     std::make_tuple(l_dstRecordName, l_dstKeywordName));
695fa5e4d32SSunny Srivastava             }
696fa5e4d32SSunny Srivastava             else
697fa5e4d32SSunny Srivastava             {
698fa5e4d32SSunny Srivastava                 l_dstKeywordVariant = utils::readDbusProperty(
699fa5e4d32SSunny Srivastava                     constants::inventoryManagerService, l_dstVpdPath,
700fa5e4d32SSunny Srivastava                     constants::ipzVpdInfPrefix + l_dstRecordName,
701fa5e4d32SSunny Srivastava                     l_dstKeywordName);
702fa5e4d32SSunny Srivastava             }
703fa5e4d32SSunny Srivastava 
704fa5e4d32SSunny Srivastava             if (auto l_dstKeywordValue =
705fa5e4d32SSunny Srivastava                     std::get_if<types::BinaryVector>(&l_dstKeywordVariant);
706fa5e4d32SSunny Srivastava                 l_dstKeywordValue && !l_dstKeywordValue->empty())
707fa5e4d32SSunny Srivastava             {
708fa5e4d32SSunny Srivastava                 l_aRecordKwInfo["destinationkeywordValue"] = *l_dstKeywordValue;
709fa5e4d32SSunny Srivastava             }
710fa5e4d32SSunny Srivastava             else
711fa5e4d32SSunny Srivastava             {
712fa5e4d32SSunny Srivastava                 // TODO: Enable logging when verbose is enabled.
713fa5e4d32SSunny Srivastava                 std::cout
714fa5e4d32SSunny Srivastava                     << "Invalid data type or empty data received, for destination record: "
715fa5e4d32SSunny Srivastava                     << l_dstRecordName << ", keyword: " << l_dstKeywordName
716fa5e4d32SSunny Srivastava                     << std::endl;
717fa5e4d32SSunny Srivastava                 continue;
718fa5e4d32SSunny Srivastava             }
719fa5e4d32SSunny Srivastava         }
720fa5e4d32SSunny Srivastava 
721fa5e4d32SSunny Srivastava         l_returnValue = true;
722fa5e4d32SSunny Srivastava     }
723fa5e4d32SSunny Srivastava     catch (const std::exception& l_ex)
724fa5e4d32SSunny Srivastava     {
725fa5e4d32SSunny Srivastava         // TODO: Enable logging when verbose is enabled.
726fa5e4d32SSunny Srivastava         std::cerr << l_ex.what() << std::endl;
727fa5e4d32SSunny Srivastava     }
728fa5e4d32SSunny Srivastava 
729fa5e4d32SSunny Srivastava     return l_returnValue;
730fa5e4d32SSunny Srivastava }
731fa5e4d32SSunny Srivastava 
getFruTypeProperty(const std::string & i_objectPath) const73243fedabcSPatrick Williams nlohmann::json VpdTool::getFruTypeProperty(
73343fedabcSPatrick Williams     const std::string& i_objectPath) const noexcept
734fa5e4d32SSunny Srivastava {
735fa5e4d32SSunny Srivastava     nlohmann::json l_resultInJson = nlohmann::json::object({});
736fa5e4d32SSunny Srivastava     std::vector<std::string> l_pimInfList;
737fa5e4d32SSunny Srivastava 
738fa5e4d32SSunny Srivastava     auto l_serviceInfMap = utils::GetServiceInterfacesForObject(
739fa5e4d32SSunny Srivastava         i_objectPath, std::vector<std::string>{constants::inventoryItemInf});
740fa5e4d32SSunny Srivastava     if (l_serviceInfMap.contains(constants::inventoryManagerService))
741fa5e4d32SSunny Srivastava     {
742fa5e4d32SSunny Srivastava         l_pimInfList = l_serviceInfMap[constants::inventoryManagerService];
743fa5e4d32SSunny Srivastava 
744fa5e4d32SSunny Srivastava         // iterate through the list and find
745fa5e4d32SSunny Srivastava         // "xyz.openbmc_project.Inventory.Item.*"
746fa5e4d32SSunny Srivastava         for (const auto& l_interface : l_pimInfList)
747fa5e4d32SSunny Srivastava         {
748fa5e4d32SSunny Srivastava             if (l_interface.find(constants::inventoryItemInf) !=
749fa5e4d32SSunny Srivastava                     std::string::npos &&
750fa5e4d32SSunny Srivastava                 l_interface.length() >
751fa5e4d32SSunny Srivastava                     std::string(constants::inventoryItemInf).length())
752fa5e4d32SSunny Srivastava             {
753fa5e4d32SSunny Srivastava                 l_resultInJson.emplace("type", l_interface);
754fa5e4d32SSunny Srivastava             }
755fa5e4d32SSunny Srivastava         }
756fa5e4d32SSunny Srivastava     }
757fa5e4d32SSunny Srivastava     return l_resultInJson;
758fa5e4d32SSunny Srivastava }
759fa5e4d32SSunny Srivastava 
isFruPresent(const std::string & i_objectPath) const760fa5e4d32SSunny Srivastava bool VpdTool::isFruPresent(const std::string& i_objectPath) const noexcept
761fa5e4d32SSunny Srivastava {
762fa5e4d32SSunny Srivastava     bool l_returnValue{false};
763fa5e4d32SSunny Srivastava     try
764fa5e4d32SSunny Srivastava     {
765fa5e4d32SSunny Srivastava         types::DbusVariantType l_keyWordValue;
766fa5e4d32SSunny Srivastava 
767fa5e4d32SSunny Srivastava         l_keyWordValue = utils::readDbusProperty(
768fa5e4d32SSunny Srivastava             constants::inventoryManagerService, i_objectPath,
769fa5e4d32SSunny Srivastava             constants::inventoryItemInf, "Present");
770fa5e4d32SSunny Srivastava 
771fa5e4d32SSunny Srivastava         if (const auto l_value = std::get_if<bool>(&l_keyWordValue))
772fa5e4d32SSunny Srivastava         {
773fa5e4d32SSunny Srivastava             l_returnValue = *l_value;
774fa5e4d32SSunny Srivastava         }
775fa5e4d32SSunny Srivastava     }
776fa5e4d32SSunny Srivastava     catch (const std::runtime_error& l_ex)
777fa5e4d32SSunny Srivastava     {
778fa5e4d32SSunny Srivastava         // TODO: Enable logging when verbose is enabled.
779fa5e4d32SSunny Srivastava         // std::cerr << "Failed to check \"Present\" property for FRU "
780fa5e4d32SSunny Srivastava         //           << i_objectPath << " Error: " << l_ex.what() <<
781fa5e4d32SSunny Srivastava         //           std::endl;
782fa5e4d32SSunny Srivastava     }
783fa5e4d32SSunny Srivastava     return l_returnValue;
784fa5e4d32SSunny Srivastava }
785fa5e4d32SSunny Srivastava 
printFixSystemVpdOption(const types::UserOption & i_option) const786fa5e4d32SSunny Srivastava void VpdTool::printFixSystemVpdOption(
787fa5e4d32SSunny Srivastava     const types::UserOption& i_option) const noexcept
788fa5e4d32SSunny Srivastava {
789fa5e4d32SSunny Srivastava     switch (i_option)
790fa5e4d32SSunny Srivastava     {
791fa5e4d32SSunny Srivastava         case types::UserOption::Exit:
792fa5e4d32SSunny Srivastava             std::cout << "Enter 0 => To exit successfully : ";
793fa5e4d32SSunny Srivastava             break;
794fa5e4d32SSunny Srivastava         case types::UserOption::UseBackupDataForAll:
795fa5e4d32SSunny Srivastava             std::cout << "Enter 1 => If you choose the data on backup for all "
796fa5e4d32SSunny Srivastava                          "mismatching record-keyword pairs"
797fa5e4d32SSunny Srivastava                       << std::endl;
798fa5e4d32SSunny Srivastava             break;
799fa5e4d32SSunny Srivastava         case types::UserOption::UseSystemBackplaneDataForAll:
800fa5e4d32SSunny Srivastava             std::cout << "Enter 2 => If you choose the data on primary for all "
801fa5e4d32SSunny Srivastava                          "mismatching record-keyword pairs"
802fa5e4d32SSunny Srivastava                       << std::endl;
803fa5e4d32SSunny Srivastava             break;
804fa5e4d32SSunny Srivastava         case types::UserOption::MoreOptions:
805fa5e4d32SSunny Srivastava             std::cout << "Enter 3 => If you wish to explore more options"
806fa5e4d32SSunny Srivastava                       << std::endl;
807fa5e4d32SSunny Srivastava             break;
808fa5e4d32SSunny Srivastava         case types::UserOption::UseBackupDataForCurrent:
809fa5e4d32SSunny Srivastava             std::cout << "Enter 4 => If you choose the data on backup as the "
810fa5e4d32SSunny Srivastava                          "right value"
811fa5e4d32SSunny Srivastava                       << std::endl;
812fa5e4d32SSunny Srivastava             break;
813fa5e4d32SSunny Srivastava         case types::UserOption::UseSystemBackplaneDataForCurrent:
814fa5e4d32SSunny Srivastava             std::cout << "Enter 5 => If you choose the data on primary as the "
815fa5e4d32SSunny Srivastava                          "right value"
816fa5e4d32SSunny Srivastava                       << std::endl;
817fa5e4d32SSunny Srivastava             break;
818fa5e4d32SSunny Srivastava         case types::UserOption::NewValueOnBoth:
819fa5e4d32SSunny Srivastava             std::cout
820fa5e4d32SSunny Srivastava                 << "Enter 6 => If you wish to enter a new value to update "
821fa5e4d32SSunny Srivastava                    "both on backup and primary"
822fa5e4d32SSunny Srivastava                 << std::endl;
823fa5e4d32SSunny Srivastava             break;
824fa5e4d32SSunny Srivastava         case types::UserOption::SkipCurrent:
825fa5e4d32SSunny Srivastava             std::cout << "Enter 7 => If you wish to skip the above "
826fa5e4d32SSunny Srivastava                          "record-keyword pair"
827fa5e4d32SSunny Srivastava                       << std::endl;
828fa5e4d32SSunny Srivastava             break;
829fa5e4d32SSunny Srivastava     }
830fa5e4d32SSunny Srivastava }
831fa5e4d32SSunny Srivastava 
dumpInventory(bool i_dumpTable) const832fa5e4d32SSunny Srivastava int VpdTool::dumpInventory(bool i_dumpTable) const noexcept
833fa5e4d32SSunny Srivastava {
834fa5e4d32SSunny Srivastava     int l_rc{constants::FAILURE};
835fa5e4d32SSunny Srivastava 
836fa5e4d32SSunny Srivastava     try
837fa5e4d32SSunny Srivastava     {
838fa5e4d32SSunny Srivastava         // get all object paths under PIM
839fa5e4d32SSunny Srivastava         const auto l_objectPaths = utils::GetSubTreePaths(
840fa5e4d32SSunny Srivastava             constants::baseInventoryPath, 0,
841fa5e4d32SSunny Srivastava             std::vector<std::string>{constants::inventoryItemInf});
842fa5e4d32SSunny Srivastava 
843fa5e4d32SSunny Srivastava         if (!l_objectPaths.empty())
844fa5e4d32SSunny Srivastava         {
845fa5e4d32SSunny Srivastava             nlohmann::json l_resultInJson = nlohmann::json::array({});
846fa5e4d32SSunny Srivastava 
847fa5e4d32SSunny Srivastava             std::for_each(l_objectPaths.begin(), l_objectPaths.end(),
848fa5e4d32SSunny Srivastava                           [&](const auto& l_objectPath) {
849fa5e4d32SSunny Srivastava                               const auto l_fruJson =
850fa5e4d32SSunny Srivastava                                   getFruProperties(l_objectPath);
851fa5e4d32SSunny Srivastava                               if (!l_fruJson.empty())
852fa5e4d32SSunny Srivastava                               {
853fa5e4d32SSunny Srivastava                                   if (l_resultInJson.empty())
854fa5e4d32SSunny Srivastava                                   {
855fa5e4d32SSunny Srivastava                                       l_resultInJson += l_fruJson;
856fa5e4d32SSunny Srivastava                                   }
857fa5e4d32SSunny Srivastava                                   else
858fa5e4d32SSunny Srivastava                                   {
859fa5e4d32SSunny Srivastava                                       l_resultInJson.at(0).insert(
860fa5e4d32SSunny Srivastava                                           l_fruJson.cbegin(), l_fruJson.cend());
861fa5e4d32SSunny Srivastava                                   }
862fa5e4d32SSunny Srivastava                               }
863fa5e4d32SSunny Srivastava                           });
864fa5e4d32SSunny Srivastava 
865fa5e4d32SSunny Srivastava             if (i_dumpTable)
866fa5e4d32SSunny Srivastava             {
867fa5e4d32SSunny Srivastava                 // create Table object
868fa5e4d32SSunny Srivastava                 utils::Table l_inventoryTable{};
869fa5e4d32SSunny Srivastava 
870fa5e4d32SSunny Srivastava                 // columns to be populated in the Inventory table
871fa5e4d32SSunny Srivastava                 const std::vector<types::TableColumnNameSizePair>
872fa5e4d32SSunny Srivastava                     l_tableColumns = {
873fa5e4d32SSunny Srivastava                         {"FRU", 100},         {"CC", 6},  {"DR", 20},
874fa5e4d32SSunny Srivastava                         {"LocationCode", 32}, {"PN", 8},  {"PrettyName", 80},
875fa5e4d32SSunny Srivastava                         {"SubModel", 10},     {"SN", 15}, {"type", 60}};
876fa5e4d32SSunny Srivastava 
877fa5e4d32SSunny Srivastava                 types::TableInputData l_tableData;
878fa5e4d32SSunny Srivastava 
879fa5e4d32SSunny Srivastava                 // First prepare the Table Columns
880fa5e4d32SSunny Srivastava                 for (const auto& l_column : l_tableColumns)
881fa5e4d32SSunny Srivastava                 {
882fa5e4d32SSunny Srivastava                     if (constants::FAILURE ==
883fa5e4d32SSunny Srivastava                         l_inventoryTable.AddColumn(l_column.first,
884fa5e4d32SSunny Srivastava                                                    l_column.second))
885fa5e4d32SSunny Srivastava                     {
886fa5e4d32SSunny Srivastava                         // TODO: Enable logging when verbose is enabled.
887fa5e4d32SSunny Srivastava                         std::cerr << "Failed to add column " << l_column.first
888fa5e4d32SSunny Srivastava                                   << " in Inventory Table." << std::endl;
889fa5e4d32SSunny Srivastava                     }
890fa5e4d32SSunny Srivastava                 }
891fa5e4d32SSunny Srivastava 
892fa5e4d32SSunny Srivastava                 // iterate through the json array
893fa5e4d32SSunny Srivastava                 for (const auto& l_fruEntry : l_resultInJson[0].items())
894fa5e4d32SSunny Srivastava                 {
895fa5e4d32SSunny Srivastava                     // if object path ends in "unit([0-9][0-9]?)", skip adding
896fa5e4d32SSunny Srivastava                     // the object path in the table
897fa5e4d32SSunny Srivastava                     if (std::regex_search(l_fruEntry.key(),
898fa5e4d32SSunny Srivastava                                           std::regex("unit([0-9][0-9]?)")))
899fa5e4d32SSunny Srivastava                     {
900fa5e4d32SSunny Srivastava                         continue;
901fa5e4d32SSunny Srivastava                     }
902fa5e4d32SSunny Srivastava 
903fa5e4d32SSunny Srivastava                     std::vector<std::string> l_row;
904fa5e4d32SSunny Srivastava                     for (const auto& l_column : l_tableColumns)
905fa5e4d32SSunny Srivastava                     {
906fa5e4d32SSunny Srivastava                         const auto& l_fruJson = l_fruEntry.value();
907fa5e4d32SSunny Srivastava 
908fa5e4d32SSunny Srivastava                         if (l_column.first == "FRU")
909fa5e4d32SSunny Srivastava                         {
910fa5e4d32SSunny Srivastava                             l_row.push_back(l_fruEntry.key());
911fa5e4d32SSunny Srivastava                         }
912fa5e4d32SSunny Srivastava                         else
913fa5e4d32SSunny Srivastava                         {
914fa5e4d32SSunny Srivastava                             if (l_fruJson.contains(l_column.first))
915fa5e4d32SSunny Srivastava                             {
916fa5e4d32SSunny Srivastava                                 l_row.push_back(l_fruJson[l_column.first]);
917fa5e4d32SSunny Srivastava                             }
918fa5e4d32SSunny Srivastava                             else
919fa5e4d32SSunny Srivastava                             {
920fa5e4d32SSunny Srivastava                                 l_row.push_back("");
921fa5e4d32SSunny Srivastava                             }
922fa5e4d32SSunny Srivastava                         }
923fa5e4d32SSunny Srivastava                     }
924fa5e4d32SSunny Srivastava 
925fa5e4d32SSunny Srivastava                     l_tableData.push_back(l_row);
926fa5e4d32SSunny Srivastava                 }
927fa5e4d32SSunny Srivastava 
928fa5e4d32SSunny Srivastava                 l_rc = l_inventoryTable.Print(l_tableData);
929fa5e4d32SSunny Srivastava             }
930fa5e4d32SSunny Srivastava             else
931fa5e4d32SSunny Srivastava             {
932fa5e4d32SSunny Srivastava                 // print JSON to console
933fa5e4d32SSunny Srivastava                 utils::printJson(l_resultInJson);
934fa5e4d32SSunny Srivastava                 l_rc = constants::SUCCESS;
935fa5e4d32SSunny Srivastava             }
936fa5e4d32SSunny Srivastava         }
937fa5e4d32SSunny Srivastava     }
938fa5e4d32SSunny Srivastava     catch (const std::exception& l_ex)
939fa5e4d32SSunny Srivastava     {
940fa5e4d32SSunny Srivastava         // TODO: Enable logging when verbose is enabled.
941fa5e4d32SSunny Srivastava         std::cerr << "Dump inventory failed. Error: " << l_ex.what()
942fa5e4d32SSunny Srivastava                   << std::endl;
943fa5e4d32SSunny Srivastava     }
944fa5e4d32SSunny Srivastava     return l_rc;
945fa5e4d32SSunny Srivastava }
946fa5e4d32SSunny Srivastava 
printSystemVpd(const nlohmann::json & i_parsedJsonObj) const947fa5e4d32SSunny Srivastava void VpdTool::printSystemVpd(
948fa5e4d32SSunny Srivastava     const nlohmann::json& i_parsedJsonObj) const noexcept
949fa5e4d32SSunny Srivastava {
950fa5e4d32SSunny Srivastava     if (i_parsedJsonObj.empty() || !i_parsedJsonObj.contains("backupMap"))
951fa5e4d32SSunny Srivastava     {
952fa5e4d32SSunny Srivastava         // TODO: Enable logging when verbose is enabled.
953fa5e4d32SSunny Srivastava         std::cerr << "Invalid JSON to print system VPD" << std::endl;
954fa5e4d32SSunny Srivastava     }
955fa5e4d32SSunny Srivastava 
956fa5e4d32SSunny Srivastava     std::string l_outline(191, '=');
957fa5e4d32SSunny Srivastava     std::cout << "\nRestorable record-keyword pairs and their data on backup & "
958fa5e4d32SSunny Srivastava                  "primary.\n\n"
959fa5e4d32SSunny Srivastava               << l_outline << std::endl;
960fa5e4d32SSunny Srivastava 
961fa5e4d32SSunny Srivastava     std::cout << std::left << std::setw(6) << "S.No" << std::left
962fa5e4d32SSunny Srivastava               << std::setw(8) << "Record" << std::left << std::setw(9)
963fa5e4d32SSunny Srivastava               << "Keyword" << std::left << std::setw(75) << "Data On Backup"
964fa5e4d32SSunny Srivastava               << std::left << std::setw(75) << "Data On Primary" << std::left
965fa5e4d32SSunny Srivastava               << std::setw(14) << "Data Mismatch\n"
966fa5e4d32SSunny Srivastava               << l_outline << std::endl;
967fa5e4d32SSunny Srivastava 
968fa5e4d32SSunny Srivastava     uint8_t l_slNum = 0;
969fa5e4d32SSunny Srivastava 
970fa5e4d32SSunny Srivastava     for (const auto& l_aRecordKwInfo : i_parsedJsonObj["backupMap"])
971fa5e4d32SSunny Srivastava     {
972fa5e4d32SSunny Srivastava         if (l_aRecordKwInfo.contains("sourceRecord") ||
973fa5e4d32SSunny Srivastava             l_aRecordKwInfo.contains("sourceKeyword") ||
974fa5e4d32SSunny Srivastava             l_aRecordKwInfo.contains("destinationkeywordValue") ||
975fa5e4d32SSunny Srivastava             l_aRecordKwInfo.contains("sourcekeywordValue"))
976fa5e4d32SSunny Srivastava         {
977fa5e4d32SSunny Srivastava             std::string l_mismatchFound{
978fa5e4d32SSunny Srivastava                 (l_aRecordKwInfo["destinationkeywordValue"] !=
979fa5e4d32SSunny Srivastava                  l_aRecordKwInfo["sourcekeywordValue"])
980fa5e4d32SSunny Srivastava                     ? "YES"
981fa5e4d32SSunny Srivastava                     : "NO"};
982fa5e4d32SSunny Srivastava 
983fa5e4d32SSunny Srivastava             std::string l_splitLine(191, '-');
984fa5e4d32SSunny Srivastava 
985fa5e4d32SSunny Srivastava             try
986fa5e4d32SSunny Srivastava             {
987fa5e4d32SSunny Srivastava                 std::cout << std::left << std::setw(6)
988fa5e4d32SSunny Srivastava                           << static_cast<int>(++l_slNum) << std::left
989fa5e4d32SSunny Srivastava                           << std::setw(8)
990fa5e4d32SSunny Srivastava                           << l_aRecordKwInfo.value("sourceRecord", "")
991fa5e4d32SSunny Srivastava                           << std::left << std::setw(9)
992fa5e4d32SSunny Srivastava                           << l_aRecordKwInfo.value("sourceKeyword", "")
993fa5e4d32SSunny Srivastava                           << std::left << std::setw(75) << std::setfill(' ')
994fa5e4d32SSunny Srivastava                           << utils::getPrintableValue(
995fa5e4d32SSunny Srivastava                                  l_aRecordKwInfo["destinationkeywordValue"])
996fa5e4d32SSunny Srivastava                           << std::left << std::setw(75) << std::setfill(' ')
997fa5e4d32SSunny Srivastava                           << utils::getPrintableValue(
998fa5e4d32SSunny Srivastava                                  l_aRecordKwInfo["sourcekeywordValue"])
999fa5e4d32SSunny Srivastava                           << std::left << std::setw(14) << l_mismatchFound
1000fa5e4d32SSunny Srivastava                           << '\n'
1001fa5e4d32SSunny Srivastava                           << l_splitLine << std::endl;
1002fa5e4d32SSunny Srivastava             }
1003fa5e4d32SSunny Srivastava             catch (const std::exception& l_ex)
1004fa5e4d32SSunny Srivastava             {
1005fa5e4d32SSunny Srivastava                 // TODO: Enable logging when verbose is enabled.
1006fa5e4d32SSunny Srivastava                 std::cerr << l_ex.what() << std::endl;
1007fa5e4d32SSunny Srivastava             }
1008fa5e4d32SSunny Srivastava         }
1009fa5e4d32SSunny Srivastava     }
1010fa5e4d32SSunny Srivastava }
1011fa5e4d32SSunny Srivastava 
updateAllKeywords(const nlohmann::json & i_parsedJsonObj,bool i_useBackupData) const1012fa5e4d32SSunny Srivastava int VpdTool::updateAllKeywords(const nlohmann::json& i_parsedJsonObj,
1013fa5e4d32SSunny Srivastava                                bool i_useBackupData) const noexcept
1014fa5e4d32SSunny Srivastava {
1015fa5e4d32SSunny Srivastava     int l_rc = constants::FAILURE;
1016fa5e4d32SSunny Srivastava 
1017fa5e4d32SSunny Srivastava     if (i_parsedJsonObj.empty() || !i_parsedJsonObj.contains("source") ||
1018fa5e4d32SSunny Srivastava         !i_parsedJsonObj.contains("backupMap"))
1019fa5e4d32SSunny Srivastava     {
1020fa5e4d32SSunny Srivastava         // TODO: Enable logging when verbose is enabled.
1021fa5e4d32SSunny Srivastava         std::cerr << "Invalid JSON" << std::endl;
1022fa5e4d32SSunny Srivastava         return l_rc;
1023fa5e4d32SSunny Srivastava     }
1024fa5e4d32SSunny Srivastava 
1025fa5e4d32SSunny Srivastava     std::string l_srcVpdPath;
1026fa5e4d32SSunny Srivastava     if (auto l_vpdPath = i_parsedJsonObj["source"].value("hardwarePath", "");
1027fa5e4d32SSunny Srivastava         !l_vpdPath.empty())
1028fa5e4d32SSunny Srivastava     {
1029fa5e4d32SSunny Srivastava         l_srcVpdPath = l_vpdPath;
1030fa5e4d32SSunny Srivastava     }
1031fa5e4d32SSunny Srivastava     else if (auto l_vpdPath =
1032fa5e4d32SSunny Srivastava                  i_parsedJsonObj["source"].value("inventoryPath", "");
1033fa5e4d32SSunny Srivastava              !l_vpdPath.empty())
1034fa5e4d32SSunny Srivastava     {
1035fa5e4d32SSunny Srivastava         l_srcVpdPath = l_vpdPath;
1036fa5e4d32SSunny Srivastava     }
1037fa5e4d32SSunny Srivastava     else
1038fa5e4d32SSunny Srivastava     {
1039fa5e4d32SSunny Srivastava         // TODO: Enable logging when verbose is enabled.
1040fa5e4d32SSunny Srivastava         std::cerr << "source path information is missing in JSON" << std::endl;
1041fa5e4d32SSunny Srivastava         return l_rc;
1042fa5e4d32SSunny Srivastava     }
1043fa5e4d32SSunny Srivastava 
1044fa5e4d32SSunny Srivastava     bool l_anyMismatchFound = false;
1045fa5e4d32SSunny Srivastava     for (const auto& l_aRecordKwInfo : i_parsedJsonObj["backupMap"])
1046fa5e4d32SSunny Srivastava     {
1047fa5e4d32SSunny Srivastava         if (!l_aRecordKwInfo.contains("sourceRecord") ||
1048fa5e4d32SSunny Srivastava             !l_aRecordKwInfo.contains("sourceKeyword") ||
1049fa5e4d32SSunny Srivastava             !l_aRecordKwInfo.contains("destinationkeywordValue") ||
1050fa5e4d32SSunny Srivastava             !l_aRecordKwInfo.contains("sourcekeywordValue"))
1051fa5e4d32SSunny Srivastava         {
1052fa5e4d32SSunny Srivastava             // TODO: Enable logging when verbose is enabled.
1053fa5e4d32SSunny Srivastava             std::cerr << "Missing required information in the JSON"
1054fa5e4d32SSunny Srivastava                       << std::endl;
1055fa5e4d32SSunny Srivastava             continue;
1056fa5e4d32SSunny Srivastava         }
1057fa5e4d32SSunny Srivastava 
1058fa5e4d32SSunny Srivastava         if (l_aRecordKwInfo["sourcekeywordValue"] !=
1059fa5e4d32SSunny Srivastava             l_aRecordKwInfo["destinationkeywordValue"])
1060fa5e4d32SSunny Srivastava         {
1061fa5e4d32SSunny Srivastava             l_anyMismatchFound = true;
1062fa5e4d32SSunny Srivastava 
1063fa5e4d32SSunny Srivastava             auto l_keywordValue =
1064fa5e4d32SSunny Srivastava                 i_useBackupData ? l_aRecordKwInfo["destinationkeywordValue"]
1065fa5e4d32SSunny Srivastava                                 : l_aRecordKwInfo["sourcekeywordValue"];
1066fa5e4d32SSunny Srivastava 
1067fa5e4d32SSunny Srivastava             auto l_paramsToWrite = std::make_tuple(
1068fa5e4d32SSunny Srivastava                 l_aRecordKwInfo["sourceRecord"],
1069fa5e4d32SSunny Srivastava                 l_aRecordKwInfo["sourceKeyword"], l_keywordValue);
1070fa5e4d32SSunny Srivastava 
1071fa5e4d32SSunny Srivastava             try
1072fa5e4d32SSunny Srivastava             {
1073fa5e4d32SSunny Srivastava                 l_rc = utils::writeKeyword(l_srcVpdPath, l_paramsToWrite);
1074fa5e4d32SSunny Srivastava                 if (l_rc > 0)
1075fa5e4d32SSunny Srivastava                 {
1076fa5e4d32SSunny Srivastava                     l_rc = constants::SUCCESS;
1077fa5e4d32SSunny Srivastava                 }
1078fa5e4d32SSunny Srivastava             }
1079fa5e4d32SSunny Srivastava             catch (const std::exception& l_ex)
1080fa5e4d32SSunny Srivastava             {
1081fa5e4d32SSunny Srivastava                 // TODO: Enable logging when verbose is enabled.
1082fa5e4d32SSunny Srivastava                 std::cerr << "write keyword failed for record: "
1083fa5e4d32SSunny Srivastava                           << l_aRecordKwInfo["sourceRecord"]
1084fa5e4d32SSunny Srivastava                           << ", keyword: " << l_aRecordKwInfo["sourceKeyword"]
1085fa5e4d32SSunny Srivastava                           << ", error: " << l_ex.what() << std::ends;
1086fa5e4d32SSunny Srivastava             }
1087fa5e4d32SSunny Srivastava         }
1088fa5e4d32SSunny Srivastava     }
1089fa5e4d32SSunny Srivastava 
1090fa5e4d32SSunny Srivastava     std::string l_dataUsed =
1091fa5e4d32SSunny Srivastava         (i_useBackupData ? "data from backup" : "data from primary VPD");
1092fa5e4d32SSunny Srivastava     if (l_anyMismatchFound)
1093fa5e4d32SSunny Srivastava     {
1094fa5e4d32SSunny Srivastava         std::cout << "Data updated successfully for all mismatching "
1095fa5e4d32SSunny Srivastava                      "record-keyword pairs by choosing their corresponding "
1096fa5e4d32SSunny Srivastava                   << l_dataUsed << ". Exit successfully." << std::endl;
1097fa5e4d32SSunny Srivastava     }
1098fa5e4d32SSunny Srivastava     else
1099fa5e4d32SSunny Srivastava     {
1100fa5e4d32SSunny Srivastava         std::cout << "No mismatch found for any of the above mentioned "
1101fa5e4d32SSunny Srivastava                      "record-keyword pair. Exit successfully."
1102fa5e4d32SSunny Srivastava                   << std::endl;
1103fa5e4d32SSunny Srivastava     }
1104fa5e4d32SSunny Srivastava 
1105fa5e4d32SSunny Srivastava     return l_rc;
1106fa5e4d32SSunny Srivastava }
1107fa5e4d32SSunny Srivastava 
handleMoreOption(const nlohmann::json & i_parsedJsonObj) const1108fa5e4d32SSunny Srivastava int VpdTool::handleMoreOption(
1109fa5e4d32SSunny Srivastava     const nlohmann::json& i_parsedJsonObj) const noexcept
1110fa5e4d32SSunny Srivastava {
1111fa5e4d32SSunny Srivastava     int l_rc = constants::FAILURE;
1112fa5e4d32SSunny Srivastava 
1113fa5e4d32SSunny Srivastava     try
1114fa5e4d32SSunny Srivastava     {
1115fa5e4d32SSunny Srivastava         if (i_parsedJsonObj.empty() || !i_parsedJsonObj.contains("backupMap"))
1116fa5e4d32SSunny Srivastava         {
1117fa5e4d32SSunny Srivastava             throw std::runtime_error("Invalid JSON");
1118fa5e4d32SSunny Srivastava         }
1119fa5e4d32SSunny Srivastava 
1120fa5e4d32SSunny Srivastava         std::string l_srcVpdPath;
1121fa5e4d32SSunny Srivastava 
1122fa5e4d32SSunny Srivastava         if (auto l_vpdPath =
1123fa5e4d32SSunny Srivastava                 i_parsedJsonObj["source"].value("hardwarePath", "");
1124fa5e4d32SSunny Srivastava             !l_vpdPath.empty())
1125fa5e4d32SSunny Srivastava         {
1126fa5e4d32SSunny Srivastava             l_srcVpdPath = l_vpdPath;
1127fa5e4d32SSunny Srivastava         }
1128fa5e4d32SSunny Srivastava         else if (auto l_vpdPath =
1129fa5e4d32SSunny Srivastava                      i_parsedJsonObj["source"].value("inventoryPath", "");
1130fa5e4d32SSunny Srivastava                  !l_vpdPath.empty())
1131fa5e4d32SSunny Srivastava         {
1132fa5e4d32SSunny Srivastava             l_srcVpdPath = l_vpdPath;
1133fa5e4d32SSunny Srivastava         }
1134fa5e4d32SSunny Srivastava         else
1135fa5e4d32SSunny Srivastava         {
1136fa5e4d32SSunny Srivastava             throw std::runtime_error(
1137fa5e4d32SSunny Srivastava                 "source path information is missing in JSON");
1138fa5e4d32SSunny Srivastava         }
1139fa5e4d32SSunny Srivastava 
1140fa5e4d32SSunny Srivastava         auto updateKeywordValue =
1141fa5e4d32SSunny Srivastava             [](std::string io_vpdPath, const std::string& i_recordName,
1142fa5e4d32SSunny Srivastava                const std::string& i_keywordName,
1143fa5e4d32SSunny Srivastava                const types::BinaryVector& i_keywordValue) -> int {
1144fa5e4d32SSunny Srivastava             int l_rc = constants::FAILURE;
1145fa5e4d32SSunny Srivastava 
1146fa5e4d32SSunny Srivastava             try
1147fa5e4d32SSunny Srivastava             {
1148fa5e4d32SSunny Srivastava                 auto l_paramsToWrite = std::make_tuple(
1149fa5e4d32SSunny Srivastava                     i_recordName, i_keywordName, i_keywordValue);
1150fa5e4d32SSunny Srivastava                 l_rc = utils::writeKeyword(io_vpdPath, l_paramsToWrite);
1151fa5e4d32SSunny Srivastava 
1152fa5e4d32SSunny Srivastava                 if (l_rc > 0)
1153fa5e4d32SSunny Srivastava                 {
1154fa5e4d32SSunny Srivastava                     std::cout << std::endl
1155fa5e4d32SSunny Srivastava                               << "Data updated successfully." << std::endl;
1156fa5e4d32SSunny Srivastava                 }
1157fa5e4d32SSunny Srivastava             }
1158fa5e4d32SSunny Srivastava             catch (const std::exception& l_ex)
1159fa5e4d32SSunny Srivastava             {
1160fa5e4d32SSunny Srivastava                 // TODO: Enable log when verbose is enabled.
1161fa5e4d32SSunny Srivastava                 std::cerr << l_ex.what() << std::endl;
1162fa5e4d32SSunny Srivastava             }
1163fa5e4d32SSunny Srivastava             return l_rc;
1164fa5e4d32SSunny Srivastava         };
1165fa5e4d32SSunny Srivastava 
1166fa5e4d32SSunny Srivastava         do
1167fa5e4d32SSunny Srivastava         {
1168fa5e4d32SSunny Srivastava             int l_slNum = 0;
1169fa5e4d32SSunny Srivastava             bool l_exit = false;
1170fa5e4d32SSunny Srivastava 
1171fa5e4d32SSunny Srivastava             for (const auto& l_aRecordKwInfo : i_parsedJsonObj["backupMap"])
1172fa5e4d32SSunny Srivastava             {
1173fa5e4d32SSunny Srivastava                 if (!l_aRecordKwInfo.contains("sourceRecord") ||
1174fa5e4d32SSunny Srivastava                     !l_aRecordKwInfo.contains("sourceKeyword") ||
1175fa5e4d32SSunny Srivastava                     !l_aRecordKwInfo.contains("destinationkeywordValue") ||
1176fa5e4d32SSunny Srivastava                     !l_aRecordKwInfo.contains("sourcekeywordValue"))
1177fa5e4d32SSunny Srivastava                 {
1178fa5e4d32SSunny Srivastava                     // TODO: Enable logging when verbose is enabled.
1179fa5e4d32SSunny Srivastava                     std::cerr
1180fa5e4d32SSunny Srivastava                         << "Source or destination information is missing in the JSON."
1181fa5e4d32SSunny Srivastava                         << std::endl;
1182fa5e4d32SSunny Srivastava                     continue;
1183fa5e4d32SSunny Srivastava                 }
1184fa5e4d32SSunny Srivastava 
1185fa5e4d32SSunny Srivastava                 const std::string l_mismatchFound{
1186fa5e4d32SSunny Srivastava                     (l_aRecordKwInfo["sourcekeywordValue"] !=
1187fa5e4d32SSunny Srivastava                      l_aRecordKwInfo["destinationkeywordValue"])
1188fa5e4d32SSunny Srivastava                         ? "YES"
1189fa5e4d32SSunny Srivastava                         : "NO"};
1190fa5e4d32SSunny Srivastava 
1191fa5e4d32SSunny Srivastava                 std::cout << std::endl
1192fa5e4d32SSunny Srivastava                           << std::left << std::setw(6) << "S.No" << std::left
1193fa5e4d32SSunny Srivastava                           << std::setw(8) << "Record" << std::left
1194fa5e4d32SSunny Srivastava                           << std::setw(9) << "Keyword" << std::left
1195fa5e4d32SSunny Srivastava                           << std::setw(75) << std::setfill(' ') << "Backup Data"
1196fa5e4d32SSunny Srivastava                           << std::left << std::setw(75) << std::setfill(' ')
1197fa5e4d32SSunny Srivastava                           << "Primary Data" << std::left << std::setw(14)
1198fa5e4d32SSunny Srivastava                           << "Data Mismatch" << std::endl;
1199fa5e4d32SSunny Srivastava 
1200fa5e4d32SSunny Srivastava                 std::cout << std::left << std::setw(6)
1201fa5e4d32SSunny Srivastava                           << static_cast<int>(++l_slNum) << std::left
1202fa5e4d32SSunny Srivastava                           << std::setw(8)
1203fa5e4d32SSunny Srivastava                           << l_aRecordKwInfo.value("sourceRecord", "")
1204fa5e4d32SSunny Srivastava                           << std::left << std::setw(9)
1205fa5e4d32SSunny Srivastava                           << l_aRecordKwInfo.value("sourceKeyword", "")
1206fa5e4d32SSunny Srivastava                           << std::left << std::setw(75) << std::setfill(' ')
1207fa5e4d32SSunny Srivastava                           << utils::getPrintableValue(
1208fa5e4d32SSunny Srivastava                                  l_aRecordKwInfo["destinationkeywordValue"])
1209fa5e4d32SSunny Srivastava                           << std::left << std::setw(75) << std::setfill(' ')
1210fa5e4d32SSunny Srivastava                           << utils::getPrintableValue(
1211fa5e4d32SSunny Srivastava                                  l_aRecordKwInfo["sourcekeywordValue"])
1212fa5e4d32SSunny Srivastava                           << std::left << std::setw(14) << l_mismatchFound
1213fa5e4d32SSunny Srivastava                           << std::endl;
1214fa5e4d32SSunny Srivastava 
1215fa5e4d32SSunny Srivastava                 std::cout << std::string(191, '=') << std::endl;
1216fa5e4d32SSunny Srivastava 
1217fa5e4d32SSunny Srivastava                 if (constants::STR_CMP_SUCCESS ==
1218fa5e4d32SSunny Srivastava                     l_mismatchFound.compare("YES"))
1219fa5e4d32SSunny Srivastava                 {
1220fa5e4d32SSunny Srivastava                     printFixSystemVpdOption(
1221fa5e4d32SSunny Srivastava                         types::UserOption::UseBackupDataForCurrent);
1222fa5e4d32SSunny Srivastava                     printFixSystemVpdOption(
1223fa5e4d32SSunny Srivastava                         types::UserOption::UseSystemBackplaneDataForCurrent);
1224fa5e4d32SSunny Srivastava                     printFixSystemVpdOption(types::UserOption::NewValueOnBoth);
1225fa5e4d32SSunny Srivastava                     printFixSystemVpdOption(types::UserOption::SkipCurrent);
1226fa5e4d32SSunny Srivastava                     printFixSystemVpdOption(types::UserOption::Exit);
1227fa5e4d32SSunny Srivastava                 }
1228fa5e4d32SSunny Srivastava                 else
1229fa5e4d32SSunny Srivastava                 {
1230fa5e4d32SSunny Srivastava                     std::cout << "No mismatch found." << std::endl << std::endl;
1231fa5e4d32SSunny Srivastava                     printFixSystemVpdOption(types::UserOption::NewValueOnBoth);
1232fa5e4d32SSunny Srivastava                     printFixSystemVpdOption(types::UserOption::SkipCurrent);
1233fa5e4d32SSunny Srivastava                     printFixSystemVpdOption(types::UserOption::Exit);
1234fa5e4d32SSunny Srivastava                 }
1235fa5e4d32SSunny Srivastava 
1236fa5e4d32SSunny Srivastava                 int l_userSelectedOption = types::UserOption::Exit;
1237fa5e4d32SSunny Srivastava                 std::cin >> l_userSelectedOption;
1238fa5e4d32SSunny Srivastava 
1239fa5e4d32SSunny Srivastava                 if (types::UserOption::UseBackupDataForCurrent ==
1240fa5e4d32SSunny Srivastava                     l_userSelectedOption)
1241fa5e4d32SSunny Srivastava                 {
1242fa5e4d32SSunny Srivastava                     l_rc = updateKeywordValue(
1243fa5e4d32SSunny Srivastava                         l_srcVpdPath, l_aRecordKwInfo["sourceRecord"],
1244fa5e4d32SSunny Srivastava                         l_aRecordKwInfo["sourceKeyword"],
1245fa5e4d32SSunny Srivastava                         l_aRecordKwInfo["destinationkeywordValue"]);
1246fa5e4d32SSunny Srivastava                 }
1247fa5e4d32SSunny Srivastava                 else if (types::UserOption::UseSystemBackplaneDataForCurrent ==
1248fa5e4d32SSunny Srivastava                          l_userSelectedOption)
1249fa5e4d32SSunny Srivastava                 {
1250fa5e4d32SSunny Srivastava                     l_rc = updateKeywordValue(
1251fa5e4d32SSunny Srivastava                         l_srcVpdPath, l_aRecordKwInfo["sourceRecord"],
1252fa5e4d32SSunny Srivastava                         l_aRecordKwInfo["sourceKeyword"],
1253fa5e4d32SSunny Srivastava                         l_aRecordKwInfo["sourcekeywordValue"]);
1254fa5e4d32SSunny Srivastava                 }
1255fa5e4d32SSunny Srivastava                 else if (types::UserOption::NewValueOnBoth ==
1256fa5e4d32SSunny Srivastava                          l_userSelectedOption)
1257fa5e4d32SSunny Srivastava                 {
1258fa5e4d32SSunny Srivastava                     std::string l_newValue;
1259fa5e4d32SSunny Srivastava                     std::cout
1260fa5e4d32SSunny Srivastava                         << std::endl
1261fa5e4d32SSunny Srivastava                         << "Enter the new value to update on both "
1262fa5e4d32SSunny Srivastava                            "primary & backup. Value should be in ASCII or "
1263fa5e4d32SSunny Srivastava                            "in HEX(prefixed with 0x) : ";
1264fa5e4d32SSunny Srivastava                     std::cin >> l_newValue;
1265fa5e4d32SSunny Srivastava                     std::cout << std::endl
1266fa5e4d32SSunny Srivastava                               << std::string(191, '=') << std::endl;
1267fa5e4d32SSunny Srivastava 
1268fa5e4d32SSunny Srivastava                     try
1269fa5e4d32SSunny Srivastava                     {
1270fa5e4d32SSunny Srivastava                         l_rc = updateKeywordValue(
1271fa5e4d32SSunny Srivastava                             l_srcVpdPath, l_aRecordKwInfo["sourceRecord"],
1272fa5e4d32SSunny Srivastava                             l_aRecordKwInfo["sourceKeyword"],
1273fa5e4d32SSunny Srivastava                             utils::convertToBinary(l_newValue));
1274fa5e4d32SSunny Srivastava                     }
1275fa5e4d32SSunny Srivastava                     catch (const std::exception& l_ex)
1276fa5e4d32SSunny Srivastava                     {
1277fa5e4d32SSunny Srivastava                         // TODO: Enable logging when verbose is enabled.
1278fa5e4d32SSunny Srivastava                         std::cerr << l_ex.what() << std::endl;
1279fa5e4d32SSunny Srivastava                     }
1280fa5e4d32SSunny Srivastava                 }
1281fa5e4d32SSunny Srivastava                 else if (types::UserOption::SkipCurrent == l_userSelectedOption)
1282fa5e4d32SSunny Srivastava                 {
1283fa5e4d32SSunny Srivastava                     std::cout << std::endl
1284fa5e4d32SSunny Srivastava                               << "Skipped the above record-keyword pair. "
1285fa5e4d32SSunny Srivastava                                  "Continue to the next available pair."
1286fa5e4d32SSunny Srivastava                               << std::endl;
1287fa5e4d32SSunny Srivastava                 }
1288fa5e4d32SSunny Srivastava                 else if (types::UserOption::Exit == l_userSelectedOption)
1289fa5e4d32SSunny Srivastava                 {
1290fa5e4d32SSunny Srivastava                     std::cout << "Exit successfully" << std::endl;
1291fa5e4d32SSunny Srivastava                     l_exit = true;
1292fa5e4d32SSunny Srivastava                     break;
1293fa5e4d32SSunny Srivastava                 }
1294fa5e4d32SSunny Srivastava                 else
1295fa5e4d32SSunny Srivastava                 {
1296fa5e4d32SSunny Srivastava                     std::cout << "Provide a valid option. Retrying for the "
1297fa5e4d32SSunny Srivastava                                  "current record-keyword pair"
1298fa5e4d32SSunny Srivastava                               << std::endl;
1299fa5e4d32SSunny Srivastava                 }
1300fa5e4d32SSunny Srivastava             }
1301fa5e4d32SSunny Srivastava             if (l_exit)
1302fa5e4d32SSunny Srivastava             {
1303fa5e4d32SSunny Srivastava                 l_rc = constants::SUCCESS;
1304fa5e4d32SSunny Srivastava                 break;
1305fa5e4d32SSunny Srivastava             }
1306fa5e4d32SSunny Srivastava         } while (true);
1307fa5e4d32SSunny Srivastava     }
1308fa5e4d32SSunny Srivastava     catch (const std::exception& l_ex)
1309fa5e4d32SSunny Srivastava     {
1310fa5e4d32SSunny Srivastava         // TODO: Enable logging when verbose is enabled.
1311fa5e4d32SSunny Srivastava         std::cerr << l_ex.what() << std::endl;
1312fa5e4d32SSunny Srivastava     }
1313fa5e4d32SSunny Srivastava 
1314fa5e4d32SSunny Srivastava     return l_rc;
1315fa5e4d32SSunny Srivastava }
1316fa5e4d32SSunny Srivastava 
resetVpdOnDbus()13176be2c015SAnupama B R int VpdTool::resetVpdOnDbus()
13186be2c015SAnupama B R {
1319*844f88f9SAnupama B R     // ToDo: Limit this function to lab mode only.
1320*844f88f9SAnupama B R 
1321*844f88f9SAnupama B R     int l_rc = constants::FAILURE;
1322*844f88f9SAnupama B R     try
1323*844f88f9SAnupama B R     {
1324*844f88f9SAnupama B R         std::string l_vpdManagerStopCmd(
1325*844f88f9SAnupama B R             "systemctl stop " + std::string(constants::vpdManagerProcessName));
1326*844f88f9SAnupama B R 
1327*844f88f9SAnupama B R         std::cout << std::flush;
1328*844f88f9SAnupama B R         if (auto l_rc = std::system(l_vpdManagerStopCmd.c_str()); l_rc != 0)
1329*844f88f9SAnupama B R         {
1330*844f88f9SAnupama B R             std::cerr << "Failed to stop " << constants::vpdManagerProcessName
1331*844f88f9SAnupama B R                       << " service. Return code [" << l_rc << "]. Exiting."
1332*844f88f9SAnupama B R                       << std::endl;
1333*844f88f9SAnupama B R             return l_rc;
1334*844f88f9SAnupama B R         }
1335*844f88f9SAnupama B R 
1336*844f88f9SAnupama B R         std::string l_vpdServiceIsActiveCmd(
1337*844f88f9SAnupama B R             "systemctl is-active --quiet " +
1338*844f88f9SAnupama B R             std::string(constants::vpdManagerProcessName));
1339*844f88f9SAnupama B R 
1340*844f88f9SAnupama B R         std::cout << std::flush;
1341*844f88f9SAnupama B R         if (auto l_rc = std::system(l_vpdServiceIsActiveCmd.c_str()); l_rc == 0)
1342*844f88f9SAnupama B R         {
1343*844f88f9SAnupama B R             std::cerr
1344*844f88f9SAnupama B R                 << constants::vpdManagerProcessName
1345*844f88f9SAnupama B R                 << " service is still active, can't proceed further. Return code ["
1346*844f88f9SAnupama B R                 << l_rc << "]. Exiting." << std::endl;
1347*844f88f9SAnupama B R             return l_rc;
1348*844f88f9SAnupama B R         }
1349*844f88f9SAnupama B R 
1350*844f88f9SAnupama B R         std::error_code l_ec;
1351*844f88f9SAnupama B R         if (static_cast<std::uintmax_t>(-1) ==
1352*844f88f9SAnupama B R             std::filesystem::remove_all(constants::pimPersistPath, l_ec))
1353*844f88f9SAnupama B R         {
1354*844f88f9SAnupama B R             std::cerr
1355*844f88f9SAnupama B R                 << "Error occured while removing the persisted VPD under path ["
1356*844f88f9SAnupama B R                 << constants::pimPersistPath << "]." << std::endl;
1357*844f88f9SAnupama B R 
1358*844f88f9SAnupama B R             if (l_ec)
1359*844f88f9SAnupama B R             {
1360*844f88f9SAnupama B R                 std::cerr << "Reason: " << l_ec.message() << std::endl;
1361*844f88f9SAnupama B R             }
1362*844f88f9SAnupama B R 
1363*844f88f9SAnupama B R             std::cerr << "Reboot BMC to recover the system." << std::endl;
1364*844f88f9SAnupama B R             return l_rc;
1365*844f88f9SAnupama B R         }
1366*844f88f9SAnupama B R 
1367*844f88f9SAnupama B R         std::string l_pimServiceRestartCmd(
1368*844f88f9SAnupama B R             "systemctl restart " +
1369*844f88f9SAnupama B R             std::string(constants::inventoryManagerService));
1370*844f88f9SAnupama B R 
1371*844f88f9SAnupama B R         std::cout << std::flush;
1372*844f88f9SAnupama B R         if (auto l_rc = std::system(l_pimServiceRestartCmd.c_str()); l_rc != 0)
1373*844f88f9SAnupama B R         {
1374*844f88f9SAnupama B R             std::cerr << "Failed to restart "
1375*844f88f9SAnupama B R                       << constants::inventoryManagerService
1376*844f88f9SAnupama B R                       << " service. Return code [" << l_rc << "]. Exiting."
1377*844f88f9SAnupama B R                       << std::endl
1378*844f88f9SAnupama B R                       << "Reboot BMC to recover the system." << std::endl;
1379*844f88f9SAnupama B R             return l_rc;
1380*844f88f9SAnupama B R         }
1381*844f88f9SAnupama B R 
1382*844f88f9SAnupama B R         std::string l_pimServiceIsActiveCmd(
1383*844f88f9SAnupama B R             "systemctl is-active --quiet " +
1384*844f88f9SAnupama B R             std::string(constants::inventoryManagerService));
1385*844f88f9SAnupama B R 
1386*844f88f9SAnupama B R         std::cout << std::flush;
1387*844f88f9SAnupama B R         if (auto l_rc = std::system(l_pimServiceIsActiveCmd.c_str()); l_rc != 0)
1388*844f88f9SAnupama B R         {
1389*844f88f9SAnupama B R             std::cerr << constants::inventoryManagerService
1390*844f88f9SAnupama B R                       << " service is not active. Return code [" << l_rc
1391*844f88f9SAnupama B R                       << "]. Exiting." << std::endl
1392*844f88f9SAnupama B R                       << "Reboot BMC to recover the system." << std::endl;
1393*844f88f9SAnupama B R             return l_rc;
1394*844f88f9SAnupama B R         }
1395*844f88f9SAnupama B R 
1396*844f88f9SAnupama B R         std::string l_vpdManagerStartCmd(
1397*844f88f9SAnupama B R             "systemctl start " + std::string(constants::vpdManagerProcessName));
1398*844f88f9SAnupama B R 
1399*844f88f9SAnupama B R         std::cout << std::flush;
1400*844f88f9SAnupama B R         if (auto l_rc = std::system(l_vpdManagerStartCmd.c_str()); l_rc != 0)
1401*844f88f9SAnupama B R         {
1402*844f88f9SAnupama B R             std::cerr << "Failed to start " << constants::vpdManagerProcessName
1403*844f88f9SAnupama B R                       << " service. Return code [" << l_rc << "]. Exiting."
1404*844f88f9SAnupama B R                       << std::endl
1405*844f88f9SAnupama B R                       << "Reboot BMC to recover the system." << std::endl;
1406*844f88f9SAnupama B R             return l_rc;
1407*844f88f9SAnupama B R         }
1408*844f88f9SAnupama B R 
1409*844f88f9SAnupama B R         std::cout << std::flush;
1410*844f88f9SAnupama B R         if (auto l_rc = std::system(l_vpdServiceIsActiveCmd.c_str()); l_rc != 0)
1411*844f88f9SAnupama B R         {
1412*844f88f9SAnupama B R             std::cerr << constants::vpdManagerProcessName
1413*844f88f9SAnupama B R                       << " service is not active. Return code [" << l_rc
1414*844f88f9SAnupama B R                       << "]. Exiting." << std::endl
1415*844f88f9SAnupama B R                       << "Reboot BMC to recover the system." << std::endl;
1416*844f88f9SAnupama B R             return l_rc;
1417*844f88f9SAnupama B R         }
1418*844f88f9SAnupama B R 
1419*844f88f9SAnupama B R         l_rc = constants::SUCCESS;
1420*844f88f9SAnupama B R     }
1421*844f88f9SAnupama B R     catch (const std::exception& l_ex)
1422*844f88f9SAnupama B R     {
1423*844f88f9SAnupama B R         // TODO: Enable logging when verbose is enabled.
1424*844f88f9SAnupama B R         std::cerr << l_ex.what() << std::endl;
1425*844f88f9SAnupama B R     }
1426*844f88f9SAnupama B R 
1427*844f88f9SAnupama B R     return l_rc;
14286be2c015SAnupama B R }
14296be2c015SAnupama B R 
getVpdValueInBiosConfigManager(const std::string & i_recordName,const std::string & i_keywordName) const14307f749a6fSSouvik Roy types::BinaryVector VpdTool::getVpdValueInBiosConfigManager(
14317f749a6fSSouvik Roy     [[maybe_unused]] const std::string& i_recordName,
14327f749a6fSSouvik Roy     [[maybe_unused]] const std::string& i_keywordName) const
14337f749a6fSSouvik Roy {
14347f749a6fSSouvik Roy     types::BinaryVector l_result;
14357f749a6fSSouvik Roy     // TODO: Use Record name, Keyword name to identify BIOS attribute.
14367f749a6fSSouvik Roy     //  Get BIOS attribute value from BIOS Config Manager.
14377f749a6fSSouvik Roy     //  Convert BIOS attribute value to VPD format value in binary.
14387f749a6fSSouvik Roy     return l_result;
14397f749a6fSSouvik Roy }
1440fa5e4d32SSunny Srivastava } // namespace vpd
1441