xref: /openbmc/openpower-vpd-parser/vpd-manager/include/manager.hpp (revision 1475f55eb4e75d64022920459bc4152afdd1b92d)
1 #pragma once
2 
3 #include "backup_restore.hpp"
4 #include "constants.hpp"
5 #include "gpio_monitor.hpp"
6 #include "types.hpp"
7 #include "worker.hpp"
8 
9 #include <sdbusplus/asio/object_server.hpp>
10 
11 namespace vpd
12 {
13 /**
14  * @brief Class to manage VPD processing.
15  *
16  * The class is responsible to implement methods to manage VPD on the system.
17  * It also implements methods to be exposed over D-Bus required to access/edit
18  * VPD data.
19  */
20 class Manager
21 {
22   public:
23     /**
24      * List of deleted methods.
25      */
26     Manager(const Manager&) = delete;
27     Manager& operator=(const Manager&) = delete;
28     Manager(Manager&&) = delete;
29 
30     /**
31      * @brief Constructor.
32      *
33      * @param[in] ioCon - IO context.
34      * @param[in] iFace - interface to implement.
35      * @param[in] connection - Dbus Connection.
36      */
37     Manager(const std::shared_ptr<boost::asio::io_context>& ioCon,
38             const std::shared_ptr<sdbusplus::asio::dbus_interface>& iFace,
39             const std::shared_ptr<sdbusplus::asio::connection>& asioConnection);
40 
41     /**
42      * @brief Destructor.
43      */
44     ~Manager() = default;
45 
46     /**
47      * @brief Update keyword value.
48      *
49      * This API is used to update keyword value on the given input path and its
50      * redundant path(s) if any taken from system config JSON.
51      *
52      * To update IPZ type VPD, input parameter for writing should be in the form
53      * of (Record, Keyword, Value). Eg: ("VINI", "SN", {0x01, 0x02, 0x03}).
54      *
55      * To update Keyword type VPD, input parameter for writing should be in the
56      * form of (Keyword, Value). Eg: ("PE", {0x01, 0x02, 0x03}).
57      *
58      * @param[in] i_vpdPath - Path (inventory object path/FRU EEPROM path).
59      * @param[in] i_paramsToWriteData - Input details.
60      *
61      * @return On success returns number of bytes written, on failure returns
62      * -1.
63      */
64     int updateKeyword(const types::Path i_vpdPath,
65                       const types::WriteVpdParams i_paramsToWriteData);
66 
67     /**
68      * @brief Update keyword value on hardware.
69      *
70      * This API is used to update keyword value on hardware. Updates only on the
71      * given input hardware path, does not look for corresponding redundant or
72      * primary path against the given path. To update corresponding paths, make
73      * separate call with respective path.
74      *
75      * To update IPZ type VPD, input parameter for writing should be in the form
76      * of (Record, Keyword, Value). Eg: ("VINI", "SN", {0x01, 0x02, 0x03}).
77      *
78      * To update Keyword type VPD, input parameter for writing should be in the
79      * form of (Keyword, Value). Eg: ("PE", {0x01, 0x02, 0x03}).
80      *
81      * @param[in] i_fruPath - EEPROM path of the FRU.
82      * @param[in] i_paramsToWriteData - Input details.
83      *
84      * @return On success returns number of bytes written, on failure returns
85      * -1.
86      */
87     int updateKeywordOnHardware(
88         const types::Path i_fruPath,
89         const types::WriteVpdParams i_paramsToWriteData) noexcept;
90 
91     /**
92      * @brief Read keyword value.
93      *
94      * API can be used to read VPD keyword from the given input path.
95      *
96      * To read keyword of type IPZ, input parameter for reading should be in the
97      * form of (Record, Keyword). Eg: ("VINI", "SN").
98      *
99      * To read keyword from keyword type VPD, just keyword name has to be
100      * supplied in the input parameter. Eg: ("SN").
101      *
102      * @param[in] i_fruPath - EEPROM path.
103      * @param[in] i_paramsToReadData - Input details.
104      *
105      * @throw
106      * sdbusplus::xyz::openbmc_project::Common::Device::Error::ReadFailure.
107      *
108      * @return On success returns the read value in variant of array of bytes.
109      * On failure throws exception.
110      */
111     types::DbusVariantType readKeyword(
112         const types::Path i_fruPath,
113         const types::ReadVpdParams i_paramsToReadData);
114 
115     /**
116      * @brief Collect single FRU VPD
117      * API can be used to perform VPD collection for the given FRU, only if the
118      * current state of the system matches with the state at which the FRU is
119      * allowed for VPD recollection.
120      *
121      * @param[in] i_dbusObjPath - D-bus object path
122      */
123     void collectSingleFruVpd(
124         const sdbusplus::message::object_path& i_dbusObjPath);
125 
126     /**
127      * @brief Delete single FRU VPD
128      * API can be used to perform VPD deletion for the given FRU.
129      *
130      * @param[in] i_dbusObjPath - D-bus object path
131      */
132     void deleteSingleFruVpd(
133         const sdbusplus::message::object_path& i_dbusObjPath);
134 
135     /**
136      * @brief Get expanded location code.
137      *
138      * API to get expanded location code from the unexpanded location code.
139      *
140      * @param[in] i_unexpandedLocationCode - Unexpanded location code.
141      * @param[in] i_nodeNumber - Denotes the node in case of a multi-node
142      * configuration, defaulted to zero incase of single node system.
143      *
144      * @throw xyz.openbmc_project.Common.Error.InvalidArgument for
145      * invalid argument.
146      *
147      * @return Location code of the FRU.
148      */
149     std::string getExpandedLocationCode(
150         const std::string& i_unexpandedLocationCode,
151         [[maybe_unused]] const uint16_t i_nodeNumber = 0);
152 
153     /**
154      * @brief Get D-Bus object path of FRUs from expanded location code.
155      *
156      * An API to get list of FRU D-Bus object paths for a given expanded
157      * location code.
158      *
159      * @param[in] i_expandedLocationCode - Expanded location code.
160      *
161      * @throw xyz.openbmc_project.Common.Error.InvalidArgument for
162      * invalid argument.
163      *
164      * @return List of FRUs D-Bus object paths for the given location code.
165      */
166     types::ListOfPaths getFrusByExpandedLocationCode(
167         const std::string& i_expandedLocationCode);
168 
169     /**
170      * @brief Get D-Bus object path of FRUs from unexpanded location code.
171      *
172      * An API to get list of FRU D-Bus object paths for a given unexpanded
173      * location code.
174      *
175      * @param[in] i_unexpandedLocationCode - Unexpanded location code.
176      * @param[in] i_nodeNumber - Denotes the node in case of a multi-node
177      * configuration, defaulted to zero incase of single node system.
178      *
179      * @throw xyz.openbmc_project.Common.Error.InvalidArgument for
180      * invalid argument.
181      *
182      * @return List of FRUs D-Bus object paths for the given location code.
183      */
184     types::ListOfPaths getFrusByUnexpandedLocationCode(
185         const std::string& i_unexpandedLocationCode,
186         [[maybe_unused]] const uint16_t i_nodeNumber = 0);
187 
188     /**
189      * @brief Get Hardware path
190      * API can be used to get EEPROM path for the given inventory path.
191      *
192      * @param[in] i_dbusObjPath - D-bus object path
193      *
194      * @return Corresponding EEPROM path.
195      */
196     std::string getHwPath(const sdbusplus::message::object_path& i_dbusObjPath);
197 
198     /**
199      * @brief  Perform VPD recollection
200      * This api will trigger parser to perform VPD recollection for FRUs that
201      * can be replaced at standby.
202      */
203     void performVpdRecollection();
204 
205     /**
206      * @brief Get unexpanded location code.
207      *
208      * An API to get unexpanded location code and node number from expanded
209      * location code.
210      *
211      * @param[in] i_expandedLocationCode - Expanded location code.
212      *
213      * @throw xyz.openbmc_project.Common.Error.InvalidArgument for
214      * invalid argument.
215      *
216      * @return Location code in unexpanded format and its node number.
217      */
218     std::tuple<std::string, uint16_t> getUnexpandedLocationCode(
219         const std::string& i_expandedLocationCode);
220 
221   private:
222 #ifdef IBM_SYSTEM
223     /**
224      * @brief API to set timer to detect system VPD over D-Bus.
225      *
226      * System VPD is required before bus name for VPD-Manager is claimed. Once
227      * system VPD is published, VPD for other FRUs should be collected. This API
228      * detects id system VPD is already published on D-Bus and based on that
229      * triggers VPD collection for rest of the FRUs.
230      *
231      * Note: Throws exception in case of any failure. Needs to be handled by the
232      * caller.
233      */
234     void SetTimerToDetectSVPDOnDbus();
235 
236     /**
237      * @brief Set timer to detect and set VPD collection status for the system.
238      *
239      * Collection of FRU VPD is triggered in a separate thread. Resulting in
240      * multiple threads at  a given time. The API creates a timer which on
241      * regular interval will check if all the threads were collected back and
242      * sets the status of the VPD collection for the system accordingly.
243      *
244      * @throw std::runtime_error
245      */
246     void SetTimerToDetectVpdCollectionStatus();
247 
248     /**
249      * @brief API to register callback for "AssetTag" property change.
250      */
251     void registerAssetTagChangeCallback();
252 
253     /**
254      * @brief Callback API to be triggered on "AssetTag" property change.
255      *
256      * @param[in] i_msg - The callback message.
257      */
258     void processAssetTagChangeCallback(sdbusplus::message_t& i_msg);
259 
260     /**
261      * @brief API to process VPD collection thread failed EEPROMs.
262      */
263     void processFailedEeproms();
264 
265     /**
266      * @brief API to check and update PowerVS VPD.
267      *
268      * The API will read the existing data from the DBus and if found
269      * different than what has been read from JSON, it will update the VPD with
270      * JSON data on hardware and DBus both.
271      *
272      * @param[in] i_powerVsJsonObj - PowerVS JSON object.
273      * @param[out] o_failedPathList - List of path failed to update.
274      */
275     void checkAndUpdatePowerVsVpd(const nlohmann::json& i_powerVsJsonObj,
276                                   std::vector<std::string>& o_failedPathList);
277 
278     /**
279      * @brief API to handle configuration w.r.t. PowerVS systems.
280      *
281      * Some FRUs VPD is specific to powerVS system. The API detects the
282      * powerVS configuration and updates the VPD accordingly.
283      */
284     void ConfigurePowerVsSystem();
285 #endif
286 
287     /**
288      * @brief An api to check validity of unexpanded location code.
289      *
290      * @param[in] i_locationCode - Unexpanded location code.
291      *
292      * @return True/False based on validity check.
293      */
294     bool isValidUnexpandedLocationCode(const std::string& i_locationCode);
295 
296     /**
297      * @brief API to register callback for Host state change.
298      */
299     void registerHostStateChangeCallback();
300 
301     /**
302      * @brief API to process host state change callback.
303      *
304      * @param[in] i_msg - Callback message.
305      */
306     void hostStateChangeCallBack(sdbusplus::message_t& i_msg);
307 
308     // Shared pointer to asio context object.
309     const std::shared_ptr<boost::asio::io_context>& m_ioContext;
310 
311     // Shared pointer to Dbus interface class.
312     const std::shared_ptr<sdbusplus::asio::dbus_interface>& m_interface;
313 
314     // Shared pointer to bus connection.
315     const std::shared_ptr<sdbusplus::asio::connection>& m_asioConnection;
316 
317     // Shared pointer to worker class
318     std::shared_ptr<Worker> m_worker;
319 
320     // Shared pointer to GpioMonitor class
321     std::shared_ptr<GpioMonitor> m_gpioMonitor;
322 
323     // Variable to hold current collection status
324     std::string m_vpdCollectionStatus = "NotStarted";
325 
326     // Shared pointer to backup and restore class
327     std::shared_ptr<BackupAndRestore> m_backupAndRestoreObj;
328 };
329 
330 } // namespace vpd
331