1 #include "config.h"
2 
3 #include "editor_impl.hpp"
4 #include "ibm_vpd_utils.hpp"
5 #include "types.hpp"
6 
7 #include <nlohmann/json.hpp>
8 #include <string>
9 
10 using json = nlohmann::json;
11 
12 // <S.no, Record, Keyword, D-Bus value, HW value, Data mismatch>
13 using SystemCriticalData =
14     std::vector<std::tuple<int, std::string, std::string, std::string,
15                            std::string, std::string>>;
16 
17 class VpdTool
18 {
19   private:
20     const std::string fruPath;
21     const std::string recordName;
22     const std::string keyword;
23     const std::string value;
24     bool objFound = true;
25     SystemCriticalData recKwData;
26 
27     // Store Type of FRU
28     std::string fruType;
29 
30     /**
31      * @brief Debugger
32      * Displays the output in JSON.
33      *
34      * @param[in] output - json output to be displayed
35      */
36     void debugger(json output);
37 
38     /**
39      * @brief make Dbus Call
40      *
41      * @param[in] objectName - dbus Object
42      * @param[in] interface - dbus Interface
43      * @param[in] kw - keyword under the interface
44      *
45      * @return dbus call response
46      */
47     auto makeDBusCall(const std::string& objectName,
48                       const std::string& interface, const std::string& kw);
49 
50     /**
51      * @brief Get VINI properties
52      * Making a dbus call for properties [SN, PN, CC, FN, DR]
53      * under VINI interface.
54      *
55      * @param[in] invPath - Value of inventory Path
56      *
57      * @return json output which gives the properties under invPath's VINI
58      * interface
59      */
60     json getVINIProperties(std::string invPath);
61 
62     /**
63      * @brief Get ExtraInterface Properties
64      * Making a dbus call for those properties under extraInterfaces.
65      *
66      * @param[in] invPath - Value of inventory path
67      * @param[in] extraInterface - One of the invPath's extraInterfaces whose
68      * value is not null
69      * @param[in] prop - All properties of the extraInterface.
70      * @param[out] output - output json which has the properties under invPath's
71      * extra interface.
72      */
73     void getExtraInterfaceProperties(const std::string& invPath,
74                                      const std::string& extraInterface,
75                                      const json& prop, json& output);
76 
77     /**
78      * @brief Interface Decider
79      * Decides whether to make the dbus call for
80      * getting properites from extraInterface or from
81      * VINI interface, depending on the value of
82      * extraInterfaces object in the inventory json.
83      *
84      * @param[in] itemEEPROM - holds the reference of one of the EEPROM objects.
85      *
86      * @return json output for one of the EEPROM objects.
87      */
88     json interfaceDecider(json& itemEEPROM);
89 
90     /**
91      * @brief Parse Inventory JSON
92      * Parses the complete inventory json and depending upon
93      * the user option makes the dbuscall for the frus
94      * via interfaceDecider function.
95      *
96      * @param[in] jsObject - Inventory json object
97      * @param[in] flag - flag which tells about the user option(either
98      * dumpInventory or dumpObject)
99      * @param[in] fruPath - fruPath is empty for dumpInventory option and holds
100      *                      valid fruPath for dumpObject option.
101      *
102      * @return output json
103      */
104     json parseInvJson(const json& jsObject, char flag, std::string fruPath);
105 
106     /**
107      * @brief eraseInventoryPath
108      * Remove the INVENTORY_PATH - "/xyz/openbmc_project/inventory"
109      * for code convenience.
110      *
111      * @param[out] fru - Reference to the fru path whose INVENTORY_PATH is
112      * stripped off.
113      */
114     void eraseInventoryPath(std::string& fru);
115 
116     /**
117      * @brief printReturnCode
118      * Prints the return code of the program in console output, whenever
119      * the program fails to exit successfully.
120      *
121      * @param[in] returnCode - return code of the program.
122      */
123     void printReturnCode(int returnCode);
124 
125     /**
126      * @brief Convert hex/ascii values to Binary
127      * @param[in] - value in hex/ascii.
128      * @param[out] - value in binary.
129      */
130     openpower::vpd::Binary toBinary(const std::string& value);
131 
132     /**
133      * @brief Get the json which has Present property value of the given fru.
134      * @param[in] invPath - inventory path of the fru.
135      * @param[out] parentPresence - Update the parent fru's present property.
136      * @return output json which has the Present property value.
137      */
138     json getPresentPropJson(const std::string& invPath,
139                             std::string& parentPresence);
140 
141     /**
142      * @brief Parse through the options to fix system VPD
143      *
144      * @param[in] json - Inventory JSON
145      */
146     void parseSVPDOptions(const nlohmann::json& json);
147 
148     /**
149      * @brief List of user options that can be used to fix system VPD keywords.
150      */
151     enum UserOption
152     {
153         EXIT = 0,
154         BMC_DATA_FOR_ALL = 1,
155         SYSTEM_BACKPLANE_DATA_FOR_ALL = 2,
156         MORE_OPTIONS = 3,
157         BMC_DATA_FOR_CURRENT = 4,
158         SYSTEM_BACKPLANE_DATA_FOR_CURRENT = 5,
159         NEW_VALUE_ON_BOTH = 6,
160         SKIP_CURRENT = 7
161     };
162 
163     /**
164      * @brief Print options to fix system VPD.
165      * @param[in] option - Option to use.
166      */
167     void printFixSystemVPDOption(UserOption option);
168 
169     /**
170      * @brief Get System VPD data stored in cache
171      *
172      * @param[in] svpdBusData - Map of system VPD record data.
173      */
174     void getSystemDataFromCache(
175         openpower::vpd::inventory::IntfPropMap& svpdBusData);
176 
177   public:
178     /**
179      * @brief Dump the complete inventory in JSON format
180      *
181      * @param[in] jsObject - Inventory JSON specified in configure file.
182      */
183     void dumpInventory(const nlohmann::basic_json<>& jsObject);
184 
185     /**
186      * @brief Dump the given inventory object in JSON format
187      *
188      * @param[in] jsObject - Inventory JSON specified in configure file.
189      */
190     void dumpObject(const nlohmann::basic_json<>& jsObject);
191 
192     /**
193      * @brief Read keyword
194      * Read the given object path, record name and keyword
195      * from the inventory and display the value of the keyword
196      * in JSON format.
197      */
198     void readKeyword();
199 
200     /**
201      * @brief Update Keyword
202      * Update the given keyword with the given value.
203      *
204      * @return return code (Success(0)/Failure(-1))
205      */
206     int updateKeyword();
207 
208     /**
209      * @brief Force Reset
210      * Clearing the inventory cache data and restarting the
211      * phosphor inventory manager and also retriggering all the
212      * udev events.
213      *
214      * @param[in] jsObject - Inventory JSON specified in configure file.
215      */
216     void forceReset(const nlohmann::basic_json<>& jsObject);
217 
218     /**
219      * @brief Update Hardware
220      * The given data is updated only on the given hardware path and not on dbus
221      * for the given record-keyword pair. The user can now update record-keyword
222      * value for any hardware path irrespective of whether its present or not in
223      * VPD JSON, by providing a valid offset. By default offset takes 0.
224      *
225      * @param[in] offset - VPD offset.
226      * @return returncode (success/failure).
227      */
228     int updateHardware(const uint32_t offset);
229 
230     /**
231      * @brief Read Keyword from Hardware
232      * This api is to read a keyword directly from the hardware. The hardware
233      * path, record name and keyword name are received at the time of
234      * initialising the constructor.
235      * The user can now read keyword from any hardware path irrespective of
236      * whether its present or not in VPD JSON, by providing a valid offset. By
237      * default offset takes 0.
238      *
239      * @param[in] startOffset - VPD offset.
240      */
241     void readKwFromHw(const uint32_t& startOffset);
242 
243     /**
244      * @brief Fix System VPD keyword.
245      * This API provides an interactive way to fix system VPD keywords that are
246      * part of restorable record-keyword pairs. The user can use this option to
247      * restore the restorable keywords in cache or in hardware or in both cache
248      * and hardware.
249      * @return returncode (success/failure).
250      */
251     int fixSystemVPD();
252 
253     /**
254      * @brief Clean specific keywords in system backplane VPD
255      *
256      * @return return code (success/failure)
257      */
258     int cleanSystemVPD();
259 
260     /**
261      * @brief Constructor
262      * Constructor is called during the
263      * object instantiation for dumpInventory option and
264      * forceReset option.
265      */
266     VpdTool()
267     {
268     }
269 
270     /**
271      * @brief Constructor
272      * Constructor is called during the
273      * object instantiation for dumpObject option.
274      */
275     VpdTool(const std::string&& fru) : fruPath(std::move(fru))
276     {
277     }
278 
279     /**
280      * @brief Constructor
281      * Constructor is called during the
282      * object instantiation for readKeyword option.
283      */
284     VpdTool(const std::string&& fru, const std::string&& recName,
285             const std::string&& kw) :
286         fruPath(std::move(fru)),
287         recordName(std::move(recName)), keyword(std::move(kw))
288     {
289     }
290 
291     /**
292      * @brief Constructor
293      * Constructor is called during the
294      * object instantiation for updateKeyword option.
295      */
296 
297     VpdTool(const std::string&& fru, const std::string&& recName,
298             const std::string&& kw, const std::string&& val) :
299         fruPath(std::move(fru)),
300         recordName(std::move(recName)), keyword(std::move(kw)),
301         value(std::move(val))
302     {
303     }
304 };
305