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