blob: 4a6a9efb8733adad26cafe4ddca59b0d3be5ecfa [file] [log] [blame]
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -05001#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
10namespace 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 */
19class 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 */
Patrick Williams43fedab2025-02-03 14:28:05 -0500110 types::DbusVariantType readKeyword(
111 const types::Path i_fruPath,
112 const types::ReadVpdParams i_paramsToReadData);
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500113
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 */
Patrick Williams43fedab2025-02-03 14:28:05 -0500217 std::tuple<std::string, uint16_t> getUnexpandedLocationCode(
218 const std::string& i_expandedLocationCode);
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500219
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);
Souvik Roy1f4c8f82025-01-23 00:37:43 -0600258
259 /**
260 * @brief API to process VPD collection thread failed EEPROMs.
261 */
262 void processFailedEeproms();
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500263#endif
264
265 /**
266 * @brief An api to check validity of unexpanded location code.
267 *
268 * @param[in] i_locationCode - Unexpanded location code.
269 *
270 * @return True/False based on validity check.
271 */
272 bool isValidUnexpandedLocationCode(const std::string& i_locationCode);
273
274 /**
275 * @brief API to register callback for Host state change.
276 */
277 void registerHostStateChangeCallback();
278
279 /**
280 * @brief API to process host state change callback.
281 *
282 * @param[in] i_msg - Callback message.
283 */
284 void hostStateChangeCallBack(sdbusplus::message_t& i_msg);
285
286 // Shared pointer to asio context object.
287 const std::shared_ptr<boost::asio::io_context>& m_ioContext;
288
289 // Shared pointer to Dbus interface class.
290 const std::shared_ptr<sdbusplus::asio::dbus_interface>& m_interface;
291
292 // Shared pointer to bus connection.
293 const std::shared_ptr<sdbusplus::asio::connection>& m_asioConnection;
294
295 // Shared pointer to worker class
296 std::shared_ptr<Worker> m_worker;
297
298 // Shared pointer to GpioMonitor class
299 std::shared_ptr<GpioMonitor> m_gpioMonitor;
300
301 // Variable to hold current collection status
302 std::string m_vpdCollectionStatus = "NotStarted";
303};
304
305} // namespace vpd