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