xref: /openbmc/openpower-vpd-parser/vpd-tool/include/vpd_tool.hpp (revision df9e554f24b31d5f9048ba8c1610c3cdb36cdac6)
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         [[maybe_unused]] const std::string& i_recordName,
221         [[maybe_unused]] const std::string& i_keywordName) const;
222 
223   public:
224     /**
225      * @brief Read keyword value.
226      *
227      * API to read VPD keyword's value from the given input path.
228      * If the provided i_onHardware option is true, read keyword's value from
229      * the hardware. Otherwise read keyword's value from DBus.
230      *
231      * @param[in] i_vpdPath - DBus object path or EEPROM path.
232      * @param[in] i_recordName - Record name.
233      * @param[in] i_keywordName - Keyword name.
234      * @param[in] i_onHardware - True if i_vpdPath is EEPROM path, false
235      * otherwise.
236      * @param[in] i_fileToSave - File path to save keyword's value, if not given
237      * result will redirect to a console.
238      *
239      * @return On success return 0, otherwise return -1.
240      */
241     int readKeyword(const std::string& i_vpdPath,
242                     const std::string& i_recordName,
243                     const std::string& i_keywordName, const bool i_onHardware,
244                     const std::string& i_fileToSave = {});
245 
246     /**
247      * @brief Dump the given inventory object in JSON format to console.
248      *
249      * For a given object path of a FRU, this API dumps the following properties
250      * of the FRU in JSON format to console:
251      * - Pretty Name, Location Code, Sub Model
252      * - SN, PN, CC, FN, DR keywords under VINI record.
253      * If the FRU's "Present" property is not true, the above properties are not
254      * dumped to console.
255      *
256      * @param[in] i_fruPath - DBus object path.
257      *
258      * @return On success returns 0, otherwise returns -1.
259      */
260     int dumpObject(std::string i_fruPath) const noexcept;
261 
262     /**
263      * @brief API to fix system VPD keywords.
264      *
265      * The API to fix the system VPD keywords. Mainly used when there
266      * is a mismatch between the primary and backup(secondary) VPD. User can
267      * choose option to update all primary keywords value with corresponding
268      * backup keywords value or can choose primary keyword value to sync
269      * secondary VPD. Otherwise, user can also interactively choose different
270      * action for individual keyword.
271      *
272      * @return On success returns 0, otherwise returns -1.
273      */
274     int fixSystemVpd() const noexcept;
275 
276     /**
277      * @brief Write keyword's value.
278      *
279      * API to update VPD keyword's value to the given input path.
280      * If i_onHardware value in true, i_vpdPath is considered has hardware path
281      * otherwise it will be considered as DBus object path.
282      *
283      * For provided DBus object path both primary path or secondary path will
284      * get updated, also redundant EEPROM(if any) path with new keyword's value.
285      *
286      * In case of hardware path, only given hardware path gets updated with new
287      * keyword’s value, any backup or redundant EEPROM (if exists) paths won't
288      * get updated.
289      *
290      * @param[in] i_vpdPath - DBus object path or EEPROM path.
291      * @param[in] i_recordName - Record name.
292      * @param[in] i_keywordName - Keyword name.
293      * @param[in] i_keywordValue - Keyword value.
294      * @param[in] i_onHardware - True if i_vpdPath is EEPROM path, false
295      * otherwise.
296      *
297      * @return On success returns 0, otherwise returns -1.
298      */
299     int writeKeyword(std::string i_vpdPath, const std::string& i_recordName,
300                      const std::string& i_keywordName,
301                      const std::string& i_keywordValue,
302                      const bool i_onHardware) noexcept;
303 
304     /**
305      * @brief Reset specific keywords on System VPD to default value.
306      *
307      * This API resets specific System VPD keywords to default value. The
308      * keyword values are reset on:
309      * 1. Primary EEPROM path.
310      * 2. Secondary EEPROM path.
311      * 3. D-Bus cache.
312      * 4. Backup path.
313      *
314      * @param[in] i_syncBiosAttributesRequired - Flag which specifies whether
315      * BIOS attribute related keywords need to be synced from BIOS Config
316      * Manager instead of being reset to default value.
317      *
318      * @return On success returns 0, otherwise returns -1.
319      */
320     int cleanSystemVpd(
321         bool i_syncBiosAttributesRequired = false) const noexcept;
322 
323     /**
324      * @brief Dump all the inventory objects in JSON or table format to console.
325      *
326      * This API dumps specific properties of all the inventory objects to
327      * console in JSON or table format to console. The inventory object paths
328      * are extracted from PIM. For each object, the following properties are
329      * dumped to console:
330      * - Present property, Pretty Name, Location Code, Sub Model
331      * - SN, PN, CC, FN, DR keywords under VINI record.
332      * If the "Present" property of a FRU is false, the FRU is not dumped to
333      * console.
334      * FRUs whose object path end in "unit([0-9][0-9]?)" are also not dumped to
335      * console.
336      *
337      * @param[in] i_dumpTable - Flag which specifies if the inventory should be
338      * dumped in table format or not.
339      *
340      * @return On success returns 0, otherwise returns -1.
341      */
342     int dumpInventory(bool i_dumpTable = false) const noexcept;
343 
344     /**
345      * @brief Resets the VPD on DBus for all the Frus.
346      *
347      * API clears the inventory persisted data and restarts the phosphor
348      * inventory manager(PIM) DBus service and the VPD manager service. VPD
349      * manager service collects the VPD for all the FRU's listed on the system
350      * config JSON and calls PIM to publish VPD on DBus.
351      *
352      * @return On success returns 0, otherwise returns -1.
353      */
354     int resetVpdOnDbus();
355 };
356 } // namespace vpd
357