1abb87edaSPriyangaRamasamy #include "config.h"
2abb87edaSPriyangaRamasamy 
3abb87edaSPriyangaRamasamy #include "defines.hpp"
4abb87edaSPriyangaRamasamy #include "ibm_vpd_type_check.hpp"
5abb87edaSPriyangaRamasamy #include "keyword_vpd_parser.hpp"
6abb87edaSPriyangaRamasamy #include "parser.hpp"
7abb87edaSPriyangaRamasamy #include "utils.hpp"
8abb87edaSPriyangaRamasamy 
9abb87edaSPriyangaRamasamy #include <CLI/CLI.hpp>
10*88edeb6fSSantosh Puranik #include <algorithm>
11abb87edaSPriyangaRamasamy #include <exception>
12abb87edaSPriyangaRamasamy #include <fstream>
13abb87edaSPriyangaRamasamy #include <iostream>
14abb87edaSPriyangaRamasamy #include <iterator>
15abb87edaSPriyangaRamasamy #include <nlohmann/json.hpp>
16abb87edaSPriyangaRamasamy 
17abb87edaSPriyangaRamasamy using namespace std;
18abb87edaSPriyangaRamasamy using namespace openpower::vpd;
19abb87edaSPriyangaRamasamy using namespace CLI;
20abb87edaSPriyangaRamasamy using namespace vpd::keyword::parser;
21abb87edaSPriyangaRamasamy using namespace vpdFormat;
22abb87edaSPriyangaRamasamy 
23abb87edaSPriyangaRamasamy /** @brief Encodes a keyword for D-Bus.
24abb87edaSPriyangaRamasamy  */
25abb87edaSPriyangaRamasamy static string encodeKeyword(const string& kw, const string& encoding)
26abb87edaSPriyangaRamasamy {
27abb87edaSPriyangaRamasamy     if (encoding == "MAC")
28abb87edaSPriyangaRamasamy     {
29abb87edaSPriyangaRamasamy         string res{};
30abb87edaSPriyangaRamasamy         size_t first = kw[0];
31abb87edaSPriyangaRamasamy         res += toHex(first >> 4);
32abb87edaSPriyangaRamasamy         res += toHex(first & 0x0f);
33abb87edaSPriyangaRamasamy         for (size_t i = 1; i < kw.size(); ++i)
34abb87edaSPriyangaRamasamy         {
35abb87edaSPriyangaRamasamy             res += ":";
36abb87edaSPriyangaRamasamy             res += toHex(kw[i] >> 4);
37abb87edaSPriyangaRamasamy             res += toHex(kw[i] & 0x0f);
38abb87edaSPriyangaRamasamy         }
39abb87edaSPriyangaRamasamy         return res;
40abb87edaSPriyangaRamasamy     }
4131970dedSAlpana Kumari     else if (encoding == "DATE")
4231970dedSAlpana Kumari     {
4331970dedSAlpana Kumari         // Date, represent as
4431970dedSAlpana Kumari         // <year>-<month>-<day> <hour>:<min>
4531970dedSAlpana Kumari         string res{};
4631970dedSAlpana Kumari         static constexpr uint8_t skipPrefix = 3;
4731970dedSAlpana Kumari 
4831970dedSAlpana Kumari         auto strItr = kw.begin();
4931970dedSAlpana Kumari         advance(strItr, skipPrefix);
5031970dedSAlpana Kumari         for_each(strItr, kw.end(), [&res](size_t c) { res += c; });
5131970dedSAlpana Kumari 
5231970dedSAlpana Kumari         res.insert(BD_YEAR_END, 1, '-');
5331970dedSAlpana Kumari         res.insert(BD_MONTH_END, 1, '-');
5431970dedSAlpana Kumari         res.insert(BD_DAY_END, 1, ' ');
5531970dedSAlpana Kumari         res.insert(BD_HOUR_END, 1, ':');
5631970dedSAlpana Kumari 
5731970dedSAlpana Kumari         return res;
5831970dedSAlpana Kumari     }
59abb87edaSPriyangaRamasamy     else // default to string encoding
60abb87edaSPriyangaRamasamy     {
61abb87edaSPriyangaRamasamy         return string(kw.begin(), kw.end());
62abb87edaSPriyangaRamasamy     }
63abb87edaSPriyangaRamasamy }
64abb87edaSPriyangaRamasamy 
65*88edeb6fSSantosh Puranik /** @brief Reads a property from the inventory manager given object path,
66*88edeb6fSSantosh Puranik  * intreface and property.
67*88edeb6fSSantosh Puranik  */
68*88edeb6fSSantosh Puranik static auto readBusProperty(const string& obj, const string& inf,
69*88edeb6fSSantosh Puranik                             const string& prop)
70*88edeb6fSSantosh Puranik {
71*88edeb6fSSantosh Puranik     string propVal{};
72*88edeb6fSSantosh Puranik     static constexpr auto OBJ_PREFIX = "/xyz/openbmc_project/inventory";
73*88edeb6fSSantosh Puranik     string object = OBJ_PREFIX + obj;
74*88edeb6fSSantosh Puranik     auto bus = sdbusplus::bus::new_default();
75*88edeb6fSSantosh Puranik     auto properties = bus.new_method_call(
76*88edeb6fSSantosh Puranik         "xyz.openbmc_project.Inventory.Manager", object.c_str(),
77*88edeb6fSSantosh Puranik         "org.freedesktop.DBus.Properties", "Get");
78*88edeb6fSSantosh Puranik     properties.append(inf);
79*88edeb6fSSantosh Puranik     properties.append(prop);
80*88edeb6fSSantosh Puranik     auto result = bus.call(properties);
81*88edeb6fSSantosh Puranik     if (!result.is_method_error())
82*88edeb6fSSantosh Puranik     {
83*88edeb6fSSantosh Puranik         variant<Binary> val;
84*88edeb6fSSantosh Puranik         result.read(val);
85*88edeb6fSSantosh Puranik 
86*88edeb6fSSantosh Puranik         if (auto pVal = get_if<Binary>(&val))
87*88edeb6fSSantosh Puranik         {
88*88edeb6fSSantosh Puranik             propVal.assign(reinterpret_cast<const char*>(pVal->data()),
89*88edeb6fSSantosh Puranik                            pVal->size());
90*88edeb6fSSantosh Puranik         }
91*88edeb6fSSantosh Puranik     }
92*88edeb6fSSantosh Puranik     return propVal;
93*88edeb6fSSantosh Puranik }
94*88edeb6fSSantosh Puranik 
95*88edeb6fSSantosh Puranik /**
96*88edeb6fSSantosh Puranik  * @brief Expands location codes
97*88edeb6fSSantosh Puranik  */
98*88edeb6fSSantosh Puranik static auto expandLocationCode(const string& unexpanded, const Parsed& vpdMap,
99*88edeb6fSSantosh Puranik                                bool isSystemVpd)
100*88edeb6fSSantosh Puranik {
101*88edeb6fSSantosh Puranik     auto expanded{unexpanded};
102*88edeb6fSSantosh Puranik     static constexpr auto SYSTEM_OBJECT = "/system/chassis/motherboard";
103*88edeb6fSSantosh Puranik     static constexpr auto VCEN_IF = "com.ibm.ipzvpd.VCEN";
104*88edeb6fSSantosh Puranik     static constexpr auto VSYS_IF = "com.ibm.ipzvpd.VSYS";
105*88edeb6fSSantosh Puranik     size_t idx = expanded.find("fcs");
106*88edeb6fSSantosh Puranik     try
107*88edeb6fSSantosh Puranik     {
108*88edeb6fSSantosh Puranik         if (idx != string::npos)
109*88edeb6fSSantosh Puranik         {
110*88edeb6fSSantosh Puranik             string fc{};
111*88edeb6fSSantosh Puranik             string se{};
112*88edeb6fSSantosh Puranik             if (isSystemVpd)
113*88edeb6fSSantosh Puranik             {
114*88edeb6fSSantosh Puranik                 const auto& fcData = vpdMap.at("VCEN").at("FC");
115*88edeb6fSSantosh Puranik                 const auto& seData = vpdMap.at("VCEN").at("SE");
116*88edeb6fSSantosh Puranik                 fc = string(fcData.data(), fcData.size());
117*88edeb6fSSantosh Puranik                 se = string(seData.data(), seData.size());
118*88edeb6fSSantosh Puranik             }
119*88edeb6fSSantosh Puranik             else
120*88edeb6fSSantosh Puranik             {
121*88edeb6fSSantosh Puranik                 fc = readBusProperty(SYSTEM_OBJECT, VCEN_IF, "FC");
122*88edeb6fSSantosh Puranik                 se = readBusProperty(SYSTEM_OBJECT, VCEN_IF, "SE");
123*88edeb6fSSantosh Puranik             }
124*88edeb6fSSantosh Puranik 
125*88edeb6fSSantosh Puranik             // TODO: See if ND1 can be placed in the JSON
126*88edeb6fSSantosh Puranik             expanded.replace(idx, 3, fc.substr(0, 4) + ".ND1." + se);
127*88edeb6fSSantosh Puranik         }
128*88edeb6fSSantosh Puranik         else
129*88edeb6fSSantosh Puranik         {
130*88edeb6fSSantosh Puranik             idx = expanded.find("mts");
131*88edeb6fSSantosh Puranik             if (idx != string::npos)
132*88edeb6fSSantosh Puranik             {
133*88edeb6fSSantosh Puranik                 string mt{};
134*88edeb6fSSantosh Puranik                 string se{};
135*88edeb6fSSantosh Puranik                 if (isSystemVpd)
136*88edeb6fSSantosh Puranik                 {
137*88edeb6fSSantosh Puranik                     const auto& mtData = vpdMap.at("VSYS").at("TM");
138*88edeb6fSSantosh Puranik                     const auto& seData = vpdMap.at("VSYS").at("SE");
139*88edeb6fSSantosh Puranik                     mt = string(mtData.data(), mtData.size());
140*88edeb6fSSantosh Puranik                     se = string(seData.data(), seData.size());
141*88edeb6fSSantosh Puranik                 }
142*88edeb6fSSantosh Puranik                 else
143*88edeb6fSSantosh Puranik                 {
144*88edeb6fSSantosh Puranik                     mt = readBusProperty(SYSTEM_OBJECT, VSYS_IF, "TM");
145*88edeb6fSSantosh Puranik                     se = readBusProperty(SYSTEM_OBJECT, VSYS_IF, "SE");
146*88edeb6fSSantosh Puranik                 }
147*88edeb6fSSantosh Puranik 
148*88edeb6fSSantosh Puranik                 replace(mt.begin(), mt.end(), '-', '.');
149*88edeb6fSSantosh Puranik                 expanded.replace(idx, 3, mt + "." + se);
150*88edeb6fSSantosh Puranik             }
151*88edeb6fSSantosh Puranik         }
152*88edeb6fSSantosh Puranik     }
153*88edeb6fSSantosh Puranik     catch (std::exception& e)
154*88edeb6fSSantosh Puranik     {
155*88edeb6fSSantosh Puranik         std::cerr << "Failed to expand location code with exception: "
156*88edeb6fSSantosh Puranik                   << e.what() << "\n";
157*88edeb6fSSantosh Puranik     }
158*88edeb6fSSantosh Puranik     return expanded;
159*88edeb6fSSantosh Puranik }
160*88edeb6fSSantosh Puranik 
161abb87edaSPriyangaRamasamy /**
162abb87edaSPriyangaRamasamy  * @brief Populate FRU specific interfaces.
163abb87edaSPriyangaRamasamy  *
164abb87edaSPriyangaRamasamy  * This is a common method which handles both
165abb87edaSPriyangaRamasamy  * ipz and keyword specific interfaces thus,
166abb87edaSPriyangaRamasamy  * reducing the code redundancy.
167abb87edaSPriyangaRamasamy  * @param[in] map - Reference to the innermost keyword-value map.
168abb87edaSPriyangaRamasamy  * @param[in] preIntrStr - Reference to the interface string.
169abb87edaSPriyangaRamasamy  * @param[out] interfaces - Reference to interface map.
170abb87edaSPriyangaRamasamy  */
171abb87edaSPriyangaRamasamy template <typename T>
172abb87edaSPriyangaRamasamy static void populateFruSpecificInterfaces(const T& map,
173abb87edaSPriyangaRamasamy                                           const string& preIntrStr,
174abb87edaSPriyangaRamasamy                                           inventory::InterfaceMap& interfaces)
175abb87edaSPriyangaRamasamy {
176abb87edaSPriyangaRamasamy     inventory::PropertyMap prop;
177abb87edaSPriyangaRamasamy 
178abb87edaSPriyangaRamasamy     for (const auto& kwVal : map)
179abb87edaSPriyangaRamasamy     {
180abb87edaSPriyangaRamasamy         std::vector<uint8_t> vec(kwVal.second.begin(), kwVal.second.end());
181abb87edaSPriyangaRamasamy 
182abb87edaSPriyangaRamasamy         auto kw = kwVal.first;
183abb87edaSPriyangaRamasamy 
184abb87edaSPriyangaRamasamy         if (kw[0] == '#')
185abb87edaSPriyangaRamasamy         {
186abb87edaSPriyangaRamasamy             kw = std::string("PD_") + kw[1];
187abb87edaSPriyangaRamasamy         }
188abb87edaSPriyangaRamasamy         prop.emplace(move(kw), move(vec));
189abb87edaSPriyangaRamasamy     }
190abb87edaSPriyangaRamasamy 
191abb87edaSPriyangaRamasamy     interfaces.emplace(preIntrStr, move(prop));
192abb87edaSPriyangaRamasamy }
193abb87edaSPriyangaRamasamy 
194abb87edaSPriyangaRamasamy /**
195abb87edaSPriyangaRamasamy  * @brief Populate Interfaces.
196abb87edaSPriyangaRamasamy  *
197abb87edaSPriyangaRamasamy  * This method populates common and extra interfaces to dbus.
198abb87edaSPriyangaRamasamy  * @param[in] js - json object
199abb87edaSPriyangaRamasamy  * @param[out] interfaces - Reference to interface map
200abb87edaSPriyangaRamasamy  * @param[in] vpdMap - Reference to the parsed vpd map.
201*88edeb6fSSantosh Puranik  * @param[in] isSystemVpd - Denotes whether we are collecting the system VPD.
202abb87edaSPriyangaRamasamy  */
203abb87edaSPriyangaRamasamy template <typename T>
204abb87edaSPriyangaRamasamy static void populateInterfaces(const nlohmann::json& js,
205abb87edaSPriyangaRamasamy                                inventory::InterfaceMap& interfaces,
206*88edeb6fSSantosh Puranik                                const T& vpdMap, bool isSystemVpd)
207abb87edaSPriyangaRamasamy {
208abb87edaSPriyangaRamasamy     for (const auto& ifs : js.items())
209abb87edaSPriyangaRamasamy     {
210*88edeb6fSSantosh Puranik         string inf = ifs.key();
211abb87edaSPriyangaRamasamy         inventory::PropertyMap props;
212abb87edaSPriyangaRamasamy 
213abb87edaSPriyangaRamasamy         for (const auto& itr : ifs.value().items())
214abb87edaSPriyangaRamasamy         {
215*88edeb6fSSantosh Puranik             const string& busProp = itr.key();
216*88edeb6fSSantosh Puranik 
21731970dedSAlpana Kumari             if (itr.value().is_boolean())
21831970dedSAlpana Kumari             {
219*88edeb6fSSantosh Puranik                 props.emplace(busProp, itr.value().get<bool>());
220*88edeb6fSSantosh Puranik             }
221*88edeb6fSSantosh Puranik             else if (itr.value().is_string())
222*88edeb6fSSantosh Puranik             {
223*88edeb6fSSantosh Puranik                 if constexpr (std::is_same<T, Parsed>::value)
224*88edeb6fSSantosh Puranik                 {
225*88edeb6fSSantosh Puranik                     if (busProp == "LocationCode" &&
226*88edeb6fSSantosh Puranik                         inf == "com.ibm.ipzvpd.Location")
227*88edeb6fSSantosh Puranik                     {
228*88edeb6fSSantosh Puranik                         auto prop = expandLocationCode(
229*88edeb6fSSantosh Puranik                             itr.value().get<string>(), vpdMap, isSystemVpd);
230*88edeb6fSSantosh Puranik                         props.emplace(busProp, prop);
231*88edeb6fSSantosh Puranik                     }
232*88edeb6fSSantosh Puranik                     else
233*88edeb6fSSantosh Puranik                     {
234*88edeb6fSSantosh Puranik                         props.emplace(busProp, itr.value().get<string>());
235*88edeb6fSSantosh Puranik                     }
236*88edeb6fSSantosh Puranik                 }
237*88edeb6fSSantosh Puranik                 else
238*88edeb6fSSantosh Puranik                 {
239*88edeb6fSSantosh Puranik                     props.emplace(busProp, itr.value().get<string>());
240*88edeb6fSSantosh Puranik                 }
24131970dedSAlpana Kumari             }
24231970dedSAlpana Kumari             else if (itr.value().is_object())
24331970dedSAlpana Kumari             {
244abb87edaSPriyangaRamasamy                 const string& rec = itr.value().value("recordName", "");
245abb87edaSPriyangaRamasamy                 const string& kw = itr.value().value("keywordName", "");
246abb87edaSPriyangaRamasamy                 const string& encoding = itr.value().value("encoding", "");
247abb87edaSPriyangaRamasamy 
248abb87edaSPriyangaRamasamy                 if constexpr (std::is_same<T, Parsed>::value)
249abb87edaSPriyangaRamasamy                 {
250*88edeb6fSSantosh Puranik                     if (!rec.empty() && !kw.empty() && vpdMap.count(rec) &&
251*88edeb6fSSantosh Puranik                         vpdMap.at(rec).count(kw))
252abb87edaSPriyangaRamasamy                     {
253abb87edaSPriyangaRamasamy                         auto encoded =
254abb87edaSPriyangaRamasamy                             encodeKeyword(vpdMap.at(rec).at(kw), encoding);
255*88edeb6fSSantosh Puranik                         props.emplace(busProp, encoded);
256abb87edaSPriyangaRamasamy                     }
257abb87edaSPriyangaRamasamy                 }
258abb87edaSPriyangaRamasamy                 else if constexpr (std::is_same<T, KeywordVpdMap>::value)
259abb87edaSPriyangaRamasamy                 {
260abb87edaSPriyangaRamasamy                     if (!kw.empty() && vpdMap.count(kw))
261abb87edaSPriyangaRamasamy                     {
262abb87edaSPriyangaRamasamy                         auto prop =
263abb87edaSPriyangaRamasamy                             string(vpdMap.at(kw).begin(), vpdMap.at(kw).end());
264abb87edaSPriyangaRamasamy                         auto encoded = encodeKeyword(prop, encoding);
265*88edeb6fSSantosh Puranik                         props.emplace(busProp, encoded);
266abb87edaSPriyangaRamasamy                     }
267abb87edaSPriyangaRamasamy                 }
268abb87edaSPriyangaRamasamy             }
26931970dedSAlpana Kumari         }
270abb87edaSPriyangaRamasamy         interfaces.emplace(inf, move(props));
271abb87edaSPriyangaRamasamy     }
272abb87edaSPriyangaRamasamy }
273abb87edaSPriyangaRamasamy 
274abb87edaSPriyangaRamasamy /**
275abb87edaSPriyangaRamasamy  * @brief Populate Dbus.
276abb87edaSPriyangaRamasamy  *
277abb87edaSPriyangaRamasamy  * This method invokes all the populateInterface functions
278abb87edaSPriyangaRamasamy  * and notifies PIM about dbus object.
279abb87edaSPriyangaRamasamy  * @param[in] vpdMap - Either IPZ vpd map or Keyword vpd map based on the input.
280abb87edaSPriyangaRamasamy  * @param[in] js - Inventory json object
281abb87edaSPriyangaRamasamy  * @param[in] filePath - Path of the vpd file
282abb87edaSPriyangaRamasamy  * @param[in] preIntrStr - Interface string
283abb87edaSPriyangaRamasamy  */
284abb87edaSPriyangaRamasamy template <typename T>
285abb87edaSPriyangaRamasamy static void populateDbus(const T& vpdMap, nlohmann::json& js,
286abb87edaSPriyangaRamasamy                          const string& filePath, const string& preIntrStr)
287abb87edaSPriyangaRamasamy {
288abb87edaSPriyangaRamasamy     inventory::InterfaceMap interfaces;
289abb87edaSPriyangaRamasamy     inventory::ObjectMap objects;
290abb87edaSPriyangaRamasamy     inventory::PropertyMap prop;
291abb87edaSPriyangaRamasamy 
292abb87edaSPriyangaRamasamy     for (const auto& item : js["frus"][filePath])
293abb87edaSPriyangaRamasamy     {
294abb87edaSPriyangaRamasamy         const auto& objectPath = item["inventoryPath"];
295abb87edaSPriyangaRamasamy         sdbusplus::message::object_path object(objectPath);
296*88edeb6fSSantosh Puranik         auto isSystemVpd = item.value("isSystemVpd", false);
297abb87edaSPriyangaRamasamy         // Populate the VPD keywords and the common interfaces only if we
298abb87edaSPriyangaRamasamy         // are asked to inherit that data from the VPD, else only add the
299abb87edaSPriyangaRamasamy         // extraInterfaces.
300abb87edaSPriyangaRamasamy         if (item.value("inherit", true))
301abb87edaSPriyangaRamasamy         {
302abb87edaSPriyangaRamasamy             if constexpr (std::is_same<T, Parsed>::value)
303abb87edaSPriyangaRamasamy             {
304abb87edaSPriyangaRamasamy                 // Each record in the VPD becomes an interface and all keyword
305abb87edaSPriyangaRamasamy                 // within the record are properties under that interface.
306abb87edaSPriyangaRamasamy                 for (const auto& record : vpdMap)
307abb87edaSPriyangaRamasamy                 {
308abb87edaSPriyangaRamasamy                     populateFruSpecificInterfaces(
309abb87edaSPriyangaRamasamy                         record.second, preIntrStr + record.first, interfaces);
310abb87edaSPriyangaRamasamy                 }
311abb87edaSPriyangaRamasamy             }
312abb87edaSPriyangaRamasamy             else if constexpr (std::is_same<T, KeywordVpdMap>::value)
313abb87edaSPriyangaRamasamy             {
314abb87edaSPriyangaRamasamy                 populateFruSpecificInterfaces(vpdMap, preIntrStr, interfaces);
315abb87edaSPriyangaRamasamy             }
316*88edeb6fSSantosh Puranik             if (js.find("commonInterfaces") != js.end())
317*88edeb6fSSantosh Puranik             {
318*88edeb6fSSantosh Puranik                 populateInterfaces(js["commonInterfaces"], interfaces, vpdMap,
319*88edeb6fSSantosh Puranik                                    isSystemVpd);
320*88edeb6fSSantosh Puranik             }
321abb87edaSPriyangaRamasamy         }
322abb87edaSPriyangaRamasamy 
323abb87edaSPriyangaRamasamy         // Populate interfaces and properties that are common to every FRU
324abb87edaSPriyangaRamasamy         // and additional interface that might be defined on a per-FRU basis.
325abb87edaSPriyangaRamasamy         if (item.find("extraInterfaces") != item.end())
326abb87edaSPriyangaRamasamy         {
327*88edeb6fSSantosh Puranik             populateInterfaces(item["extraInterfaces"], interfaces, vpdMap,
328*88edeb6fSSantosh Puranik                                isSystemVpd);
329abb87edaSPriyangaRamasamy         }
330abb87edaSPriyangaRamasamy         objects.emplace(move(object), move(interfaces));
331abb87edaSPriyangaRamasamy     }
332abb87edaSPriyangaRamasamy 
333abb87edaSPriyangaRamasamy     // Notify PIM
334abb87edaSPriyangaRamasamy     inventory::callPIM(move(objects));
335abb87edaSPriyangaRamasamy }
336abb87edaSPriyangaRamasamy 
337abb87edaSPriyangaRamasamy int main(int argc, char** argv)
338abb87edaSPriyangaRamasamy {
339abb87edaSPriyangaRamasamy     int rc = 0;
340abb87edaSPriyangaRamasamy 
341abb87edaSPriyangaRamasamy     try
342abb87edaSPriyangaRamasamy     {
343abb87edaSPriyangaRamasamy         using json = nlohmann::json;
344abb87edaSPriyangaRamasamy 
345abb87edaSPriyangaRamasamy         App app{"ibm-read-vpd - App to read IPZ format VPD, parse it and store "
346abb87edaSPriyangaRamasamy                 "in DBUS"};
347abb87edaSPriyangaRamasamy         string file{};
348abb87edaSPriyangaRamasamy 
349abb87edaSPriyangaRamasamy         app.add_option("-f, --file", file, "File containing VPD (IPZ/KEYWORD)")
350abb87edaSPriyangaRamasamy             ->required()
351abb87edaSPriyangaRamasamy             ->check(ExistingFile);
352abb87edaSPriyangaRamasamy 
353abb87edaSPriyangaRamasamy         CLI11_PARSE(app, argc, argv);
354abb87edaSPriyangaRamasamy 
355abb87edaSPriyangaRamasamy         // Make sure that the file path we get is for a supported EEPROM
356abb87edaSPriyangaRamasamy         ifstream inventoryJson(INVENTORY_JSON);
357abb87edaSPriyangaRamasamy         auto js = json::parse(inventoryJson);
358abb87edaSPriyangaRamasamy 
359abb87edaSPriyangaRamasamy         if ((js.find("frus") == js.end()) ||
360abb87edaSPriyangaRamasamy             (js["frus"].find(file) == js["frus"].end()))
361abb87edaSPriyangaRamasamy         {
362*88edeb6fSSantosh Puranik             cout << "Device path not in JSON, ignoring" << std::endl;
363*88edeb6fSSantosh Puranik             return 0;
364abb87edaSPriyangaRamasamy         }
365abb87edaSPriyangaRamasamy 
366abb87edaSPriyangaRamasamy         // Open the file in binary mode
367abb87edaSPriyangaRamasamy         ifstream vpdFile(file, ios::binary);
368abb87edaSPriyangaRamasamy         // Read the content of the binary file into a vector
369abb87edaSPriyangaRamasamy         Binary vpdVector((istreambuf_iterator<char>(vpdFile)),
370abb87edaSPriyangaRamasamy                          istreambuf_iterator<char>());
371abb87edaSPriyangaRamasamy 
372abb87edaSPriyangaRamasamy         vpdType type = vpdTypeCheck(vpdVector);
373abb87edaSPriyangaRamasamy 
374abb87edaSPriyangaRamasamy         switch (type)
375abb87edaSPriyangaRamasamy         {
376abb87edaSPriyangaRamasamy             case IPZ_VPD:
377abb87edaSPriyangaRamasamy             {
378abb87edaSPriyangaRamasamy                 // Invoking IPZ Vpd Parser
379abb87edaSPriyangaRamasamy                 auto vpdStore = parse(move(vpdVector));
380abb87edaSPriyangaRamasamy                 const Parsed& vpdMap = vpdStore.getVpdMap();
381abb87edaSPriyangaRamasamy                 string preIntrStr = "com.ibm.ipzvpd.";
382abb87edaSPriyangaRamasamy                 // Write it to the inventory
383abb87edaSPriyangaRamasamy                 populateDbus(vpdMap, js, file, preIntrStr);
384abb87edaSPriyangaRamasamy             }
385abb87edaSPriyangaRamasamy             break;
386abb87edaSPriyangaRamasamy 
387abb87edaSPriyangaRamasamy             case KEYWORD_VPD:
388abb87edaSPriyangaRamasamy             {
389abb87edaSPriyangaRamasamy                 // Creating Keyword Vpd Parser Object
390abb87edaSPriyangaRamasamy                 KeywordVpdParser parserObj(move(vpdVector));
391abb87edaSPriyangaRamasamy                 // Invoking KW Vpd Parser
392abb87edaSPriyangaRamasamy                 const auto& kwValMap = parserObj.parseKwVpd();
393abb87edaSPriyangaRamasamy                 string preIntrStr = "com.ibm.kwvpd.KWVPD";
394abb87edaSPriyangaRamasamy                 populateDbus(kwValMap, js, file, preIntrStr);
395abb87edaSPriyangaRamasamy             }
396abb87edaSPriyangaRamasamy             break;
397abb87edaSPriyangaRamasamy             default:
398abb87edaSPriyangaRamasamy                 throw std::runtime_error("Invalid VPD format");
399abb87edaSPriyangaRamasamy         }
400abb87edaSPriyangaRamasamy     }
401abb87edaSPriyangaRamasamy     catch (exception& e)
402abb87edaSPriyangaRamasamy     {
403abb87edaSPriyangaRamasamy         cerr << e.what() << "\n";
404abb87edaSPriyangaRamasamy         rc = -1;
405abb87edaSPriyangaRamasamy     }
406abb87edaSPriyangaRamasamy 
407abb87edaSPriyangaRamasamy     return rc;
408abb87edaSPriyangaRamasamy }
409