xref: /openbmc/openpower-vpd-parser/vpd-tool/include/vpd_tool.hpp (revision 963e842d76719f5ca740ba03afabdb7aacea542e)
1 #pragma once
2 
3 #include "tool_utils.hpp"
4 
5 #include <nlohmann/json.hpp>
6 
7 #include <optional>
8 #include <string>
9 
10 namespace vpd
11 {
12 /**
13  * @brief Class to support operations on VPD.
14  *
15  * The class provides API's to,
16  * Read keyword value from DBus/hardware.
17  * Update keyword value to DBus/hardware.
18  * Dump DBus object's critical information.
19  * Fix system VPD if any mismatch between DBus and hardware data.
20  * Reset specific system VPD keywords to its default value.
21  * Force VPD collection for hardware.
22  */
23 class VpdTool
24 {
25   private:
26     /**
27      * @brief Get specific properties of a FRU in JSON format.
28      *
29      * For a given object path of a FRU, this API returns the following
30      * properties of the FRU in JSON format:
31      * - Pretty Name, Location Code, Sub Model
32      * - SN, PN, CC, FN, DR keywords under VINI record.
33      *
34      * @param[in] i_objectPath - DBus object path
35      *
36      * @return On success, returns the properties of the FRU in JSON format,
37      * otherwise returns an empty JSON.
38      * If FRU's "Present" property is false, this API returns an empty JSON.
39      * Note: The caller of this API should handle empty JSON.
40      *
41      * @throw json::exception, std::out_of_range, std::bad_alloc
42      */
43     nlohmann::json getFruProperties(const std::string& i_objectPath) const;
44 
45     /**
46      * @brief API to populate FRU JSON.
47      *
48      * The API will create FRUs JSON, which will have property value pairs for
49      * all the interfaces required for that particular FRU.
50      *
51      * @param[in] i_inventoryObjPath - FRU inventory path.
52      * @param[in, out] io_fruJsonObject - JSON object.
53      * @param[in] i_interfaceList - list of interfaces implemented by the FRU on
54      * Dbus.
55      */
56     void populateFruJson(const std::string& i_inventoryObjPath,
57                          nlohmann::json& io_fruJsonObject,
58                          const std::vector<std::string>& i_interfaceList) const;
59 
60     /**
61      * @brief API to populate JSON for an interface.
62      *
63      * The API will create interface JSON, which will have property value pairs
64      * for all the properties required under that interface.
65      *
66      * @param[in] i_inventoryObjPath - FRU inventory path.
67      * @param[in] i_infName - interface whose JSON need to be populated.
68      * @param[in] i_propList - List of properties needed in the JSON.
69      * @param[in, out] io_fruJsonObject - JSON object.
70      */
71     template <typename PropertyType>
72     void populateInterfaceJson(const std::string& i_inventoryObjPath,
73                                const std::string& i_infName,
74                                const std::vector<std::string>& i_propList,
75                                nlohmann::json& io_fruJsonObject) const;
76 
77     /**
78      * @brief Get any inventory property in JSON.
79      *
80      * API to get any property of a FRU in JSON format. Given an object path,
81      * interface and property name, this API does a D-Bus read property on PIM
82      * to get the value of that property and returns it in JSON format. This API
83      * returns empty JSON in case of failure. The caller of the API must check
84      * for empty JSON.
85      *
86      * @param[in] i_objectPath - DBus object path
87      * @param[in] i_interface - Interface name
88      * @param[in] i_propertyName - Property name
89      *
90      * @return On success, returns the property and its value in JSON format,
91      * otherwise return empty JSON.
92      * {"SN" : "ABCD"}
93      */
94     template <typename PropertyType>
95     nlohmann::json getInventoryPropertyJson(
96         const std::string& i_objectPath, const std::string& i_interface,
97         const std::string& i_propertyName) const noexcept;
98 
99     /**
100      * @brief Get the "type" property for a FRU.
101      *
102      * Given a FRU path, and parsed System Config JSON, this API returns the
103      * "type" property for the FRU in JSON format. This API gets
104      * these properties from Phosphor Inventory Manager.
105      *
106      * @param[in] i_objectPath - DBus object path.
107      *
108      * @return On success, returns the "type" property in JSON
109      * format, otherwise returns empty JSON. The caller of this API should
110      * handle empty JSON.
111      */
112     nlohmann::json getFruTypeProperty(
113         const std::string& i_objectPath) const noexcept;
114 
115     /**
116      * @brief Check if a FRU is present in the system.
117      *
118      * Given a FRU's object path, this API checks if the FRU is present in the
119      * system by reading the "Present" property of the FRU.
120      *
121      * @param[in] i_objectPath - DBus object path.
122      *
123      * @return true if FRU's "Present" property is true, false otherwise.
124      */
125     bool isFruPresent(const std::string& i_objectPath) const noexcept;
126 
127     /**
128      * @brief An API to get backup-restore config JSON of the system.
129      *
130      * API gets this file by prasing system config JSON file and reading
131      * backupRestoreConfigPath tag.
132      *
133      * @return On success returns valid JSON object, otherwise returns empty
134      * JSON object.
135      *
136      * Note: The caller of this API should verify, is received JSON object is
137      * empty or not.
138      */
139     nlohmann::json getBackupRestoreCfgJsonObj() const noexcept;
140 
141     /**
142      * @brief Prints the user options for fix system VPD command.
143      *
144      * @param[in] i_option - Option to use.
145      */
146     void printFixSystemVpdOption(
147         const types::UserOption& i_option) const noexcept;
148 
149     /**
150      * @brief API to update source and destination keyword's value.
151      *
152      * API fetches source and destination keyword's value,
153      * for each keyword entries found in the input JSON object and updates the
154      * JSON object. If the path(source / destination) in JSON object is
155      * inventory object path, API sends the request to Inventory.Manager DBus
156      * service. Otherwise if its a hardware path, API sends the request to
157      * vpd-manager DBus service to get the keyword's value.
158      *
159      * @param[in,out] io_parsedJsonObj - Parsed JSON object.
160      *
161      * @return true on success, false in case of any error.
162      */
163     bool fetchKeywordInfo(nlohmann::json& io_parsedJsonObj) const noexcept;
164 
165     /**
166      * @brief API to print system VPD keyword's information.
167      *
168      * The API prints source and destination keyword's information in the table
169      * format, found in the JSON object.
170      *
171      * @param[in] i_parsedJsonObj - Parsed JSON object.
172      */
173     void printSystemVpd(const nlohmann::json& i_parsedJsonObj) const noexcept;
174 
175     /**
176      * @brief API to update keyword's value.
177      *
178      * API iterates the given JSON object for all record-keyword pairs, if there
179      * is any mismatch between source and destination keyword's value, API calls
180      * the utils::writeKeyword API to update keyword's value.
181      *
182      * Note: writeKeyword API, internally updates primary, backup, redundant
183      * EEPROM paths(if exists) with the given keyword's value.
184      *
185      * @param i_parsedJsonObj - Parsed JSON object.
186      * @param i_useBackupData - Specifies whether to use source or destination
187      * keyword's value to update the keyword's value.
188      *
189      * @return On success return 0, otherwise return -1.
190      */
191     int updateAllKeywords(const nlohmann::json& i_parsedJsonObj,
192                           bool i_useBackupData) const noexcept;
193 
194     /**
195      * @brief API to handle more option for fix system VPD command.
196      *
197      * @param i_parsedJsonObj - Parsed JSON object.
198      *
199      * @return On success return 0, otherwise return -1.
200      */
201     int handleMoreOption(const nlohmann::json& i_parsedJsonObj) const noexcept;
202 
203     /**
204      * @brief API to get VPD value of keyword in BIOS Config Manager.
205      *
206      * For a given record and keyword, this API gets the associated BIOS
207      * attribute current value from BIOS Config Manager, by reading the
208      * attribute value from BIOS Config Manager, converts the BIOS attribute
209      * value to VPD format, and returns it.
210      *
211      * @param[in] i_recordName - Record name.
212      * @param[in] i_keywordName - Keyword name.
213      *
214      * @return On success returns the resultant keyword value in binary
215      * format, else returns empty value.
216      *
217      * @throw std::terminate, std::bad_alloc
218      */
219     types::BinaryVector getVpdValueInBiosConfigManager(
220         const std::string& i_recordName,
221         const std::string& i_keywordName) const;
222 
223     /**
224      * @brief VPD keyword to BIOS attribute map
225      *
226      * This map specifies which VPD keyword is used to backup which BIOS
227      * attribute.
228      * {Record, Keyword} -> {attribute name, number of bits in keyword, starting
229      * bit position, enabled value, disabled value}
230      *
231      */
232     static const types::BiosAttributeKeywordMap m_biosAttributeVpdKeywordMap;
233 
234   public:
235     /**
236      * @brief Read keyword value.
237      *
238      * API to read VPD keyword's value from the given input path.
239      * If the provided i_onHardware option is true, read keyword's value from
240      * the hardware. Otherwise read keyword's value from DBus.
241      *
242      * @param[in] i_vpdPath - DBus object path or EEPROM path.
243      * @param[in] i_recordName - Record name.
244      * @param[in] i_keywordName - Keyword name.
245      * @param[in] i_onHardware - True if i_vpdPath is EEPROM path, false
246      * otherwise.
247      * @param[in] i_fileToSave - File path to save keyword's value, if not given
248      * result will redirect to a console.
249      *
250      * @return On success return 0, otherwise return -1.
251      */
252     int readKeyword(const std::string& i_vpdPath,
253                     const std::string& i_recordName,
254                     const std::string& i_keywordName, const bool i_onHardware,
255                     const std::string& i_fileToSave = {});
256 
257     /**
258      * @brief Dump the given inventory object in JSON format to console.
259      *
260      * For a given object path of a FRU, this API dumps the following properties
261      * of the FRU in JSON format to console:
262      * - Pretty Name, Location Code, Sub Model
263      * - SN, PN, CC, FN, DR keywords under VINI record.
264      * If the FRU's "Present" property is not true, the above properties are not
265      * dumped to console.
266      *
267      * @param[in] i_fruPath - DBus object path.
268      *
269      * @return On success returns 0, otherwise returns -1.
270      */
271     int dumpObject(std::string i_fruPath) const noexcept;
272 
273     /**
274      * @brief API to fix system VPD keywords.
275      *
276      * The API to fix the system VPD keywords. Mainly used when there
277      * is a mismatch between the primary and backup(secondary) VPD. User can
278      * choose option to update all primary keywords value with corresponding
279      * backup keywords value or can choose primary keyword value to sync
280      * secondary VPD. Otherwise, user can also interactively choose different
281      * action for individual keyword.
282      *
283      * @return On success returns 0, otherwise returns -1.
284      */
285     int fixSystemVpd() const noexcept;
286 
287     /**
288      * @brief Write keyword's value.
289      *
290      * API to update VPD keyword's value to the given input path.
291      * If i_onHardware value in true, i_vpdPath is considered has hardware path
292      * otherwise it will be considered as DBus object path.
293      *
294      * For provided DBus object path both primary path or secondary path will
295      * get updated, also redundant EEPROM(if any) path with new keyword's value.
296      *
297      * In case of hardware path, only given hardware path gets updated with new
298      * keyword’s value, any backup or redundant EEPROM (if exists) paths won't
299      * get updated.
300      *
301      * @param[in] i_vpdPath - DBus object path or EEPROM path.
302      * @param[in] i_recordName - Record name.
303      * @param[in] i_keywordName - Keyword name.
304      * @param[in] i_keywordValue - Keyword value.
305      * @param[in] i_onHardware - True if i_vpdPath is EEPROM path, false
306      * otherwise.
307      *
308      * @return On success returns 0, otherwise returns -1.
309      */
310     int writeKeyword(std::string i_vpdPath, const std::string& i_recordName,
311                      const std::string& i_keywordName,
312                      const std::string& i_keywordValue,
313                      const bool i_onHardware) noexcept;
314 
315     /**
316      * @brief Reset specific keywords on System VPD to default value.
317      *
318      * This API resets specific System VPD keywords to default value. The
319      * keyword values are reset on:
320      * 1. Primary EEPROM path.
321      * 2. Secondary EEPROM path.
322      * 3. D-Bus cache.
323      * 4. Backup path.
324      *
325      * @param[in] i_syncBiosAttributesRequired - Flag which specifies whether
326      * BIOS attribute related keywords need to be synced from BIOS Config
327      * Manager instead of being reset to default value.
328      *
329      * @return On success returns 0, otherwise returns -1.
330      */
331     int cleanSystemVpd(
332         bool i_syncBiosAttributesRequired = false) const noexcept;
333 
334     /**
335      * @brief Dump all the inventory objects in JSON or table format to console.
336      *
337      * This API dumps specific properties of all the inventory objects to
338      * console in JSON or table format to console. The inventory object paths
339      * are extracted from PIM. For each object, the following properties are
340      * dumped to console:
341      * - Present property, Pretty Name, Location Code, Sub Model
342      * - SN, PN, CC, FN, DR keywords under VINI record.
343      * If the "Present" property of a FRU is false, the FRU is not dumped to
344      * console.
345      * FRUs whose object path end in "unit([0-9][0-9]?)" are also not dumped to
346      * console.
347      *
348      * @param[in] i_dumpTable - Flag which specifies if the inventory should be
349      * dumped in table format or not.
350      *
351      * @return On success returns 0, otherwise returns -1.
352      */
353     int dumpInventory(bool i_dumpTable = false) const noexcept;
354 
355     /**
356      * @brief Resets the VPD on DBus for all the Frus.
357      *
358      * API clears the inventory persisted data and restarts the phosphor
359      * inventory manager(PIM) DBus service and the VPD manager service. VPD
360      * manager service collects the VPD for all the FRU's listed on the system
361      * config JSON and calls PIM to publish VPD on DBus.
362      *
363      * @return On success returns 0, otherwise returns -1.
364      */
365     int resetVpdOnDbus();
366 
367     /**
368      * @brief API to clear vpd dump directory
369      *
370      * This API deletes all the files inside vpd dump directory and then deletes
371      * the directory from the filesystem
372      */
373     void clearVpdDumpDir() const noexcept;
374 };
375 } // namespace vpd
376