blob: bdf93c197d874caf4fd8fefa32e9eefd3e949043 [file] [log] [blame]
Matt Spinlerc8705e22019-09-11 12:36:07 -05001#pragma once
2
Matt Spinler2a28c932020-02-03 14:23:40 -06003#include "dbus_types.hpp"
4#include "dbus_watcher.hpp"
5
Deepa Karthikeyanff35be32024-10-15 09:10:49 -05006#ifdef PEL_ENABLE_PHAL
7#include <libguard/guard_interface.hpp>
8#include <libguard/include/guard_record.hpp>
9#endif
10
Matt Spinlera167a7d2023-06-30 15:14:25 -050011#include <phosphor-logging/lg2.hpp>
Matt Spinlerc8705e22019-09-11 12:36:07 -050012#include <sdbusplus/bus.hpp>
13#include <sdbusplus/bus/match.hpp>
14
Arya K Padmand8ae6182024-07-19 06:25:10 -050015#include <expected>
Patrick Williams2544b412022-10-04 08:41:06 -050016#include <filesystem>
17#include <fstream>
Arya K Padmand8ae6182024-07-19 06:25:10 -050018#include <unordered_map>
Patrick Williams2544b412022-10-04 08:41:06 -050019
Deepa Karthikeyanff35be32024-10-15 09:10:49 -050020#ifdef PEL_ENABLE_PHAL
21using GardType = openpower::guard::GardType;
22namespace libguard = openpower::guard;
23#endif
24
Matt Spinlerc8705e22019-09-11 12:36:07 -050025namespace openpower
26{
27namespace pels
28{
29
Matt Spinlerc8705e22019-09-11 12:36:07 -050030/**
31 * @class DataInterface
32 *
Matt Spinler19e89ce2019-11-06 13:02:23 -060033 * A base class for gathering data about the system for use
34 * in PELs. Implemented this way to facilitate mocking.
Matt Spinlerc8705e22019-09-11 12:36:07 -050035 */
36class DataInterfaceBase
37{
38 public:
39 DataInterfaceBase() = default;
40 virtual ~DataInterfaceBase() = default;
41 DataInterfaceBase(const DataInterfaceBase&) = default;
42 DataInterfaceBase& operator=(const DataInterfaceBase&) = default;
43 DataInterfaceBase(DataInterfaceBase&&) = default;
44 DataInterfaceBase& operator=(DataInterfaceBase&&) = default;
45
46 /**
Matt Spinler19e89ce2019-11-06 13:02:23 -060047 * @brief Returns the machine Type/Model
Matt Spinlerc8705e22019-09-11 12:36:07 -050048 *
49 * @return string - The machine Type/Model string
50 */
Vijay Lobo81b4dca2021-04-29 00:04:00 -050051 virtual std::string getMachineTypeModel() const = 0;
Matt Spinlerc8705e22019-09-11 12:36:07 -050052
53 /**
Matt Spinler19e89ce2019-11-06 13:02:23 -060054 * @brief Returns the machine serial number
Matt Spinlerc8705e22019-09-11 12:36:07 -050055 *
56 * @return string - The machine serial number
57 */
Vijay Lobo81b4dca2021-04-29 00:04:00 -050058 virtual std::string getMachineSerialNumber() const = 0;
Matt Spinler19e89ce2019-11-06 13:02:23 -060059
Matt Spinlera7d9d962019-11-06 15:01:25 -060060 /**
Matt Spinlercce14112019-12-11 14:20:36 -060061 * @brief Says if the system is managed by a hardware
62 * management console.
63 * @return bool - If the system is HMC managed
64 */
65 virtual bool isHMCManaged() const
66 {
67 return _hmcManaged;
68 }
69
70 /**
Matt Spinlera7d9d962019-11-06 15:01:25 -060071 * @brief Says if the host is up and running
72 *
73 * @return bool - If the host is running
74 */
75 virtual bool isHostUp() const
76 {
77 return _hostUp;
78 }
79
80 using HostStateChangeFunc = std::function<void(bool)>;
81
82 /**
83 * @brief Register a callback function that will get
84 * called on all host on/off transitions.
85 *
86 * The void(bool) function will get passed the new
87 * value of the host state.
88 *
89 * @param[in] name - The subscription name
90 * @param[in] func - The function to run
91 */
92 void subscribeToHostStateChange(const std::string& name,
93 HostStateChangeFunc func)
94 {
95 _hostChangeCallbacks[name] = func;
96 }
97
98 /**
99 * @brief Unsubscribe from host state changes.
100 *
101 * @param[in] name - The subscription name
102 */
103 void unsubscribeFromHostStateChange(const std::string& name)
104 {
105 _hostChangeCallbacks.erase(name);
106 }
107
Matt Spinler5b423652023-05-04 13:08:44 -0500108 using FRUPresentFunc =
109 std::function<void(const std::string& /* locationCode */)>;
110
111 /**
112 * @brief Register a callback function that will get
113 * called when certain FRUs become present.
114 *
115 * The void(std::string) function will get passed the
116 * location code of the FRU.
117 *
118 * @param[in] name - The subscription name
119 * @param[in] func - The function to run
120 */
121 void subscribeToFruPresent(const std::string& name, FRUPresentFunc func)
122 {
123 _fruPresentCallbacks[name] = std::move(func);
124 }
125
Matt Spinlercad9c2b2019-12-02 15:42:01 -0600126 /**
127 * @brief Returns the BMC firmware version
128 *
129 * @return std::string - The BMC version
130 */
131 virtual std::string getBMCFWVersion() const
132 {
133 return _bmcFWVersion;
134 }
135
136 /**
137 * @brief Returns the server firmware version
138 *
139 * @return std::string - The server firmware version
140 */
141 virtual std::string getServerFWVersion() const
142 {
143 return _serverFWVersion;
144 }
145
Matt Spinler4dcd3f42020-01-22 14:55:07 -0600146 /**
Matt Spinler677381b2020-01-23 10:04:29 -0600147 * @brief Returns the BMC FW version ID
148 *
149 * @return std::string - The BMC FW version ID
150 */
151 virtual std::string getBMCFWVersionID() const
152 {
153 return _bmcFWVersionID;
154 }
155
156 /**
Matt Spinler4dcd3f42020-01-22 14:55:07 -0600157 * @brief Returns the process name given its PID.
158 *
159 * @param[in] pid - The PID value as a string
160 *
161 * @return std::optional<std::string> - The name, or std::nullopt
162 */
163 std::optional<std::string> getProcessName(const std::string& pid) const
164 {
165 namespace fs = std::filesystem;
166
167 fs::path path{"/proc"};
168 path /= fs::path{pid} / "exe";
169
170 if (fs::exists(path))
171 {
172 return fs::read_symlink(path);
173 }
174
175 return std::nullopt;
176 }
177
Matt Spinler9cf3cfd2020-02-03 14:41:55 -0600178 /**
George Liu9ac0d9b2022-07-15 10:57:38 +0800179 * @brief Returns the time the system was running.
180 *
181 * @return std::optional<uint64_t> - The System uptime or std::nullopt
182 */
183 std::optional<uint64_t> getUptimeInSeconds() const
184 {
185 std::ifstream versionFile{"/proc/uptime"};
186 std::string line{};
187
188 std::getline(versionFile, line);
189 auto pos = line.find(" ");
190 if (pos == std::string::npos)
191 {
192 return std::nullopt;
193 }
194
195 uint64_t seconds = atol(line.substr(0, pos).c_str());
196 if (seconds == 0)
197 {
198 return std::nullopt;
199 }
200
201 return seconds;
202 }
203
204 /**
205 * @brief Returns the time the system was running.
206 *
207 * @param[in] seconds - The number of seconds the system has been running
208 *
209 * @return std::string - days/hours/minutes/seconds
210 */
211 std::string getBMCUptime(uint64_t seconds) const
212 {
213 time_t t(seconds);
214 tm* p = gmtime(&t);
215
Patrick Williams075c7922024-08-16 15:19:49 -0400216 std::string uptime =
217 std::to_string(p->tm_year - 70) + "y " +
218 std::to_string(p->tm_yday) + "d " + std::to_string(p->tm_hour) +
219 "h " + std::to_string(p->tm_min) + "m " +
220 std::to_string(p->tm_sec) + "s";
George Liu9ac0d9b2022-07-15 10:57:38 +0800221
222 return uptime;
223 }
224
225 /**
226 * @brief Returns the system load average over the past 1 minute, 5 minutes
227 * and 15 minutes.
228 *
229 * @return std::string - The system load average
230 */
231 std::string getBMCLoadAvg() const
232 {
233 std::string loadavg{};
234
235 std::ifstream loadavgFile{"/proc/loadavg"};
236 std::string line;
237 std::getline(loadavgFile, line);
238
239 size_t count = 3;
240 for (size_t i = 0; i < count; i++)
241 {
242 auto pos = line.find(" ");
243 if (pos == std::string::npos)
244 {
245 return {};
246 }
247
248 if (i != count - 1)
249 {
250 loadavg.append(line.substr(0, pos + 1));
251 }
252 else
253 {
254 loadavg.append(line.substr(0, pos));
255 }
256
257 line = line.substr(pos + 1);
258 }
259
260 return loadavg;
261 }
262
263 /**
Matt Spinler9cf3cfd2020-02-03 14:41:55 -0600264 * @brief Returns the 'send event logs to host' setting.
265 *
266 * @return bool - If sending PELs to the host is enabled.
267 */
268 virtual bool getHostPELEnablement() const
269 {
270 return _sendPELsToHost;
271 }
272
Matt Spinler4aa23a12020-02-03 15:05:09 -0600273 /**
274 * @brief Returns the BMC state
275 *
276 * @return std::string - The BMC state property value
277 */
278 virtual std::string getBMCState() const
279 {
280 return _bmcState;
281 }
282
283 /**
284 * @brief Returns the Chassis state
285 *
286 * @return std::string - The chassis state property value
287 */
288 virtual std::string getChassisState() const
289 {
290 return _chassisState;
291 }
292
293 /**
294 * @brief Returns the chassis requested power
295 * transition value.
296 *
297 * @return std::string - The chassis transition property
298 */
299 virtual std::string getChassisTransition() const
300 {
301 return _chassisTransition;
302 }
303
304 /**
305 * @brief Returns the Host state
306 *
307 * @return std::string - The Host state property value
308 */
309 virtual std::string getHostState() const
310 {
311 return _hostState;
312 }
313
Matt Spinlerb3d488f2020-02-21 15:30:46 -0600314 /**
Sumit Kumar2c36fdd2021-09-21 03:12:11 -0500315 * @brief Returns the Boot state
316 *
317 * @return std::string - The Boot state property value
318 */
319 virtual std::string getBootState() const
320 {
321 return _bootState;
322 }
323
324 /**
Matt Spinlerb3d488f2020-02-21 15:30:46 -0600325 * @brief Returns the motherboard CCIN
326 *
327 * @return std::string The motherboard CCIN
328 */
Vijay Lobo81b4dca2021-04-29 00:04:00 -0500329 virtual std::string getMotherboardCCIN() const = 0;
Matt Spinlerb3d488f2020-02-21 15:30:46 -0600330
Matt Spinler60c4e792020-03-13 13:45:36 -0500331 /**
Ben Tynere32b7e72021-05-18 12:38:40 -0500332 * @brief Returns the system IM
333 *
334 * @return std::string The system IM
335 */
336 virtual std::vector<uint8_t> getSystemIMKeyword() const = 0;
337
338 /**
Matt Spinler60c4e792020-03-13 13:45:36 -0500339 * @brief Get the fields from the inventory necessary for doing
340 * a callout on an inventory path.
341 *
342 * @param[in] inventoryPath - The item to get the data for
Matt Spinler60c4e792020-03-13 13:45:36 -0500343 * @param[out] fruPartNumber - Filled in with the VINI/FN keyword
344 * @param[out] ccin - Filled in with the VINI/CC keyword
345 * @param[out] serialNumber - Filled in with the VINI/SN keyword
346 */
Patrick Williams075c7922024-08-16 15:19:49 -0400347 virtual void getHWCalloutFields(
348 const std::string& inventoryPath, std::string& fruPartNumber,
349 std::string& ccin, std::string& serialNumber) const = 0;
Matt Spinler60c4e792020-03-13 13:45:36 -0500350
Matt Spinler03984582020-04-09 13:17:58 -0500351 /**
Matt Spinler9b90e2a2020-04-14 10:59:04 -0500352 * @brief Get the location code for an inventory item.
353 *
354 * @param[in] inventoryPath - The item to get the data for
355 *
356 * @return std::string - The location code
357 */
358 virtual std::string
359 getLocationCode(const std::string& inventoryPath) const = 0;
360
361 /**
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500362 * @brief Get the list of system type names the system is called.
Matt Spinler03984582020-04-09 13:17:58 -0500363 *
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500364 * @return std::vector<std::string> - The list of names
Matt Spinler03984582020-04-09 13:17:58 -0500365 */
Matt Spinler1ab66962020-10-29 13:21:44 -0500366 virtual std::vector<std::string> getSystemNames() const = 0;
Matt Spinler03984582020-04-09 13:17:58 -0500367
Matt Spinler5fb24c12020-06-04 11:21:33 -0500368 /**
369 * @brief Fills in the placeholder 'Ufcs' in the passed in location
370 * code with the machine feature code and serial number, which
371 * is needed to create a valid location code.
372 *
373 * @param[in] locationCode - Location code value starting with Ufcs-, and
374 * if that isn't present it will be added first.
375 *
376 * @param[in] node - The node number the location is on.
377 *
378 * @return std::string - The expanded location code
379 */
380 virtual std::string expandLocationCode(const std::string& locationCode,
381 uint16_t node) const = 0;
382
383 /**
Matt Spinlerbad056b2023-01-25 14:16:57 -0600384 * @brief Returns the inventory paths for the FRU that the location
Matt Spinler5fb24c12020-06-04 11:21:33 -0500385 * code represents.
386 *
Matt Spinler2f9225a2020-08-05 12:58:49 -0500387 * @param[in] locationCode - If an expanded location code, then the
388 * full location code.
389 * If not expanded, a location code value
390 * starting with Ufcs-, and if that isn't
391 * present it will be added first.
Matt Spinler5fb24c12020-06-04 11:21:33 -0500392 *
Matt Spinler2f9225a2020-08-05 12:58:49 -0500393 * @param[in] node - The node number the location is on. Ignored if the
394 * expanded location code is passed in.
395 *
396 * @param[in] expanded - If the location code already has the relevent
397 * VPD fields embedded in it.
Matt Spinler5fb24c12020-06-04 11:21:33 -0500398 *
Matt Spinlerbad056b2023-01-25 14:16:57 -0600399 * @return std::vector<std::string> - The inventory D-Bus objects
Matt Spinler5fb24c12020-06-04 11:21:33 -0500400 */
Matt Spinlerbad056b2023-01-25 14:16:57 -0600401 virtual std::vector<std::string>
402 getInventoryFromLocCode(const std::string& LocationCode, uint16_t node,
403 bool expanded) const = 0;
Matt Spinler5fb24c12020-06-04 11:21:33 -0500404
Matt Spinler34a904c2020-08-05 14:53:28 -0500405 /**
Matt Spinler34a904c2020-08-05 14:53:28 -0500406 * @brief Sets the Asserted property on the LED group passed in.
407 *
408 * @param[in] ledGroup - The LED group D-Bus path
409 * @param[in] value - The value to set it to
410 */
411 virtual void assertLEDGroup(const std::string& ledGroup,
412 bool value) const = 0;
413
Matt Spinler993168d2021-04-07 16:05:03 -0500414 /**
415 * @brief Sets the Functional property on the OperationalStatus
416 * interface on a D-Bus object.
417 *
418 * @param[in] objectPath - The D-Bus object path
419 * @param[in] functional - The value
420 */
421 virtual void setFunctional(const std::string& objectPath,
422 bool functional) const = 0;
423
Sumit Kumar3b8ed7f2021-05-18 12:38:35 -0500424 /**
Sumit Kumar76198a22021-07-15 05:59:57 -0500425 * @brief Sets the critical association on the D-Bus object.
426 *
427 * @param[in] objectPath - The D-Bus object path
428 */
429 virtual void
430 setCriticalAssociation(const std::string& objectPath) const = 0;
431
432 /**
Sumit Kumar3b8ed7f2021-05-18 12:38:35 -0500433 * @brief Returns the manufacturing QuiesceOnError property
434 *
435 * @return bool - Manufacturing QuiesceOnError property
436 */
437 virtual bool getQuiesceOnError() const = 0;
438
Matt Spinler0d92b522021-06-16 13:28:17 -0600439 /**
440 * @brief Split location code into base and connector segments
441 *
442 * A location code that ends in '-Tx', where 'x' is a number,
443 * represents a connector, such as a USB cable connector.
444 *
445 * This function splits the passed in location code into a
446 * base and connector segment. e.g.:
447 * P0-T1 -> ['P0', '-T1']
448 * P0 -> ['P0', '']
449 *
450 * @param[in] locationCode - location code to split
451 * @return pair<string, string> - The base and connector segments
452 */
453 static std::pair<std::string, std::string>
454 extractConnectorFromLocCode(const std::string& locationCode);
455
Deepa Karthikeyanff35be32024-10-15 09:10:49 -0500456#ifdef PEL_ENABLE_PHAL
Sumit Kumar9d43a722021-08-24 09:46:19 -0500457 /**
Jayanth Othayothecaa2fc2021-11-05 02:02:52 -0500458 * @brief Create guard record
459 *
460 * @param[in] binPath: phal devtree binary path used as key
Deepa Karthikeyanff35be32024-10-15 09:10:49 -0500461 * @param[in] eGardType: Guard type enum value
462 * @param[in] plid: Pel ID
Jayanth Othayothecaa2fc2021-11-05 02:02:52 -0500463 */
464 virtual void createGuardRecord(const std::vector<uint8_t>& binPath,
Deepa Karthikeyanff35be32024-10-15 09:10:49 -0500465 GardType eGardType, uint32_t plid) const = 0;
466#endif
Jayanth Othayothecaa2fc2021-11-05 02:02:52 -0500467
Sumit Kumar3e274432021-09-14 06:37:56 -0500468 /**
469 * @brief Create Progress SRC property on the boot progress
470 * interface on a D-Bus object.
471 *
472 * @param[in] priSRC - Primary SRC value (e.g. BD8D1001)
473 * @param[in] srcStruct - Full SRC base structure
474 */
475 virtual void
476 createProgressSRC(const uint64_t& priSRC,
477 const std::vector<uint8_t>& srcStruct) const = 0;
478
Sumit Kumar027bf282022-01-24 11:25:19 -0600479 /**
480 * @brief Get the list of unresolved OpenBMC event log ids that have an
481 * associated hardware isolation entry.
482 *
483 * @return std::vector<uint32_t> - The list of log ids
484 */
485 virtual std::vector<uint32_t> getLogIDWithHwIsolation() const = 0;
486
Vijay Lobo875b6c72021-10-20 17:38:56 -0500487 /**
488 * @brief Returns the latest raw progress SRC from the State.Boot.Raw
489 * D-Bus interface.
490 *
491 * @return std::vector<uint8_t> - The progress SRC bytes
492 */
493 virtual std::vector<uint8_t> getRawProgressSRC() const = 0;
494
Arya K Padmand8ae6182024-07-19 06:25:10 -0500495 /**
496 * @brief Returns the FRUs DI property value hosted on the VINI iterface for
497 * the given location code.
498 *
499 * @param[in] locationCode - The location code of the FRU
500 *
501 * @return std::optional<std::vector<uint8_t>> - The FRUs DI or
502 * std::nullopt
503 */
504 virtual std::optional<std::vector<uint8_t>>
505 getDIProperty(const std::string& locationCode) const = 0;
506
507 /**
508 * @brief Wrpper API to call pHAL API 'getFRUType()' and check whether the
509 * given location code is DIMM or not
510 *
511 * @param[in] locCode - The location code of the FRU
512 *
Arya K Padmanced8ed72024-09-02 05:18:07 -0500513 * @return - true, if the given location code is DIMM
514 * - false, if the given location code is not DIMM or if it fails to
515 * determine the FRU type.
Arya K Padmand8ae6182024-07-19 06:25:10 -0500516 */
Arya K Padmanced8ed72024-09-02 05:18:07 -0500517 bool isDIMM(const std::string& locCode);
Arya K Padmand8ae6182024-07-19 06:25:10 -0500518
519 /**
520 * @brief Check whether the given location code present in the cache
521 * memory
522 *
523 * @param[in] locCode - The location code of the FRU
524 *
525 * @return true, if the given location code present in cache and is a DIMM
526 * false, if the given location code present in cache, but a non
527 * DIMM FRU
528 * std::nullopt, if the given location code is not present in the
529 * cache.
530 */
531 std::optional<bool> isDIMMLocCode(const std::string& locCode) const;
532
533 /**
534 * @brief add the given location code to the cache memory
535 *
536 * @param[in] locCode - The location code of the FRU
537 * @param[in] isFRUDIMM - true indicates the FRU is a DIMM
538 * false indicates the FRU is a non DIMM
539 *
540 */
541 void addDIMMLocCode(const std::string& locCode, bool isFRUDIMM);
542
harsh-agarwal1d763db32024-09-03 09:18:50 -0500543 /**
544 * @brief Finds all D-Bus Associated paths that contain any of the
545 * interfaces passed in, by using GetAssociatedSubTreePaths.
546 *
547 * @param[in] associatedPath - The D-Bus object path
548 * @param[in] subtree - The subtree path for which the result should be
549 * fetched
550 * @param[in] depth - The maximum subtree depth for which results should be
551 * fetched
552 * @param[in] interfaces - The desired interfaces
553 *
554 * @return The D-Bus paths.
555 */
556 virtual DBusPathList getAssociatedPaths(
557 const DBusPath& associatedPath, const DBusPath& subtree, int32_t depth,
558 const DBusInterfaceList& interfaces) const = 0;
559
Matt Spinler19e89ce2019-11-06 13:02:23 -0600560 protected:
561 /**
Matt Spinlera7d9d962019-11-06 15:01:25 -0600562 * @brief Sets the host on/off state and runs any
563 * callback functions (if there was a change).
564 */
Matt Spinler4aa23a12020-02-03 15:05:09 -0600565 void setHostUp(bool hostUp)
Matt Spinlera7d9d962019-11-06 15:01:25 -0600566 {
Matt Spinler4aa23a12020-02-03 15:05:09 -0600567 if (_hostUp != hostUp)
Matt Spinlera7d9d962019-11-06 15:01:25 -0600568 {
Matt Spinler4aa23a12020-02-03 15:05:09 -0600569 _hostUp = hostUp;
Matt Spinlera7d9d962019-11-06 15:01:25 -0600570
571 for (auto& [name, func] : _hostChangeCallbacks)
572 {
573 try
574 {
575 func(_hostUp);
576 }
Patrick Williams66491c62021-10-06 12:23:37 -0500577 catch (const std::exception& e)
Matt Spinlera7d9d962019-11-06 15:01:25 -0600578 {
Matt Spinlera167a7d2023-06-30 15:14:25 -0500579 lg2::error(
580 "A host state change callback threw an exception");
Matt Spinlera7d9d962019-11-06 15:01:25 -0600581 }
582 }
583 }
584 }
585
586 /**
Matt Spinler5b423652023-05-04 13:08:44 -0500587 * @brief Runs the callback functions registered when
588 * FRUs become present.
589 */
590 void setFruPresent(const std::string& locationCode)
591 {
592 for (const auto& [_, func] : _fruPresentCallbacks)
593 {
594 try
595 {
596 func(locationCode);
597 }
598 catch (const std::exception& e)
599 {
Matt Spinlera167a7d2023-06-30 15:14:25 -0500600 lg2::error("A FRU present callback threw an exception");
Matt Spinler5b423652023-05-04 13:08:44 -0500601 }
602 }
603 }
604
605 /**
Matt Spinlercce14112019-12-11 14:20:36 -0600606 * @brief The hardware management console status. Always kept
607 * up to date.
608 */
609 bool _hmcManaged = false;
610
611 /**
Matt Spinlera7d9d962019-11-06 15:01:25 -0600612 * @brief The host up status. Always kept up to date.
613 */
614 bool _hostUp = false;
615
616 /**
617 * @brief The map of host state change subscriber
618 * names to callback functions.
619 */
620 std::map<std::string, HostStateChangeFunc> _hostChangeCallbacks;
Matt Spinlercad9c2b2019-12-02 15:42:01 -0600621
622 /**
Matt Spinler5b423652023-05-04 13:08:44 -0500623 * @brief The map of FRU present subscriber
624 * names to callback functions.
625 */
626 std::map<std::string, FRUPresentFunc> _fruPresentCallbacks;
627
628 /**
Matt Spinlercad9c2b2019-12-02 15:42:01 -0600629 * @brief The BMC firmware version string
630 */
631 std::string _bmcFWVersion;
632
633 /**
634 * @brief The server firmware version string
635 */
636 std::string _serverFWVersion;
Matt Spinler677381b2020-01-23 10:04:29 -0600637
638 /**
639 * @brief The BMC firmware version ID string
640 */
641 std::string _bmcFWVersionID;
Matt Spinler9cf3cfd2020-02-03 14:41:55 -0600642
643 /**
644 * @brief If sending PELs is enabled.
645 *
646 * This is usually set to false in manufacturing test.
647 */
648 bool _sendPELsToHost = true;
Matt Spinler4aa23a12020-02-03 15:05:09 -0600649
650 /**
651 * @brief The BMC state property
652 */
653 std::string _bmcState;
654
655 /**
656 * @brief The Chassis current power state property
657 */
658 std::string _chassisState;
659
660 /**
661 * @brief The Chassis requested power transition property
662 */
663 std::string _chassisTransition;
664
665 /**
666 * @brief The host state property
667 */
668 std::string _hostState;
Sumit Kumar2c36fdd2021-09-21 03:12:11 -0500669
670 /**
671 * @brief The boot state property
672 */
673 std::string _bootState;
Arya K Padmand8ae6182024-07-19 06:25:10 -0500674
675 /**
676 * @brief A cache storage for location code and its FRU Type
677 * - The key 'std::string' represents the locationCode of the FRU
678 * - The bool value - true indicates the FRU is a DIMM
679 * false indicates the FRU is a non DIMM.
680 */
681 std::unordered_map<std::string, bool> _locationCache;
Matt Spinlerc8705e22019-09-11 12:36:07 -0500682};
683
684/**
685 * @class DataInterface
686 *
687 * Concrete implementation of DataInterfaceBase.
688 */
689class DataInterface : public DataInterfaceBase
690{
691 public:
692 DataInterface() = delete;
693 ~DataInterface() = default;
694 DataInterface(const DataInterface&) = default;
695 DataInterface& operator=(const DataInterface&) = default;
696 DataInterface(DataInterface&&) = default;
697 DataInterface& operator=(DataInterface&&) = default;
698
699 /**
700 * @brief Constructor
701 *
702 * @param[in] bus - The sdbusplus bus object
703 */
Patrick Williams45e83522022-07-22 19:26:52 -0500704 explicit DataInterface(sdbusplus::bus_t& bus);
Matt Spinlerc8705e22019-09-11 12:36:07 -0500705
Matt Spinlerb3f51862019-12-09 13:55:10 -0600706 /**
Matt Spinlerc8705e22019-09-11 12:36:07 -0500707 * @brief Finds the D-Bus service name that hosts the
708 * passed in path and interface.
709 *
710 * @param[in] objectPath - The D-Bus object path
711 * @param[in] interface - The D-Bus interface
712 */
713 DBusService getService(const std::string& objectPath,
Matt Spinlerb3f51862019-12-09 13:55:10 -0600714 const std::string& interface) const;
Matt Spinler9cf3cfd2020-02-03 14:41:55 -0600715
Matt Spinlerc8705e22019-09-11 12:36:07 -0500716 /**
717 * @brief Wrapper for the 'GetAll' properties method call
718 *
719 * @param[in] service - The D-Bus service to call it on
720 * @param[in] objectPath - The D-Bus object path
721 * @param[in] interface - The interface to get the props on
722 *
723 * @return DBusPropertyMap - The property results
724 */
725 DBusPropertyMap getAllProperties(const std::string& service,
726 const std::string& objectPath,
Matt Spinler2a28c932020-02-03 14:23:40 -0600727 const std::string& interface) const;
Matt Spinlerc8705e22019-09-11 12:36:07 -0500728 /**
Matt Spinlera7d9d962019-11-06 15:01:25 -0600729 * @brief Wrapper for the 'Get' properties method call
730 *
731 * @param[in] service - The D-Bus service to call it on
732 * @param[in] objectPath - The D-Bus object path
733 * @param[in] interface - The interface to get the property on
734 * @param[in] property - The property name
735 * @param[out] value - Filled in with the property value.
736 */
737 void getProperty(const std::string& service, const std::string& objectPath,
738 const std::string& interface, const std::string& property,
Matt Spinler2a28c932020-02-03 14:23:40 -0600739 DBusValue& value) const;
Vijay Lobo81b4dca2021-04-29 00:04:00 -0500740 /**
741 * @brief Returns the machine Type/Model
742 *
743 * @return string - The machine Type/Model string
744 */
745 std::string getMachineTypeModel() const override;
746
747 /**
748 * @brief Returns the machine serial number
749 *
750 * @return string - The machine serial number
751 */
752 std::string getMachineSerialNumber() const override;
753
754 /**
755 * @brief Returns the motherboard CCIN
756 *
757 * @return std::string The motherboard CCIN
758 */
759 std::string getMotherboardCCIN() const override;
Matt Spinler2a28c932020-02-03 14:23:40 -0600760
Matt Spinler60c4e792020-03-13 13:45:36 -0500761 /**
Ben Tynere32b7e72021-05-18 12:38:40 -0500762 * @brief Returns the system IM
763 *
764 * @return std::vector The system IM keyword in 4 byte vector
765 */
766 std::vector<uint8_t> getSystemIMKeyword() const override;
767
768 /**
Matt Spinler60c4e792020-03-13 13:45:36 -0500769 * @brief Get the fields from the inventory necessary for doing
770 * a callout on an inventory path.
771 *
772 * @param[in] inventoryPath - The item to get the data for
Matt Spinler60c4e792020-03-13 13:45:36 -0500773 * @param[out] fruPartNumber - Filled in with the VINI/FN keyword
774 * @param[out] ccin - Filled in with the VINI/CC keyword
775 * @param[out] serialNumber - Filled in with the VINI/SN keyword
776 */
777 void getHWCalloutFields(const std::string& inventoryPath,
Matt Spinler60c4e792020-03-13 13:45:36 -0500778 std::string& fruPartNumber, std::string& ccin,
779 std::string& serialNumber) const override;
780
Matt Spinler9b90e2a2020-04-14 10:59:04 -0500781 /**
782 * @brief Get the location code for an inventory item.
783 *
784 * Throws an exception if the inventory item doesn't have the
785 * location code interface.
786 *
787 * @param[in] inventoryPath - The item to get the data for
788 *
789 * @return std::string - The location code
790 */
791 std::string
792 getLocationCode(const std::string& inventoryPath) const override;
793
Matt Spinler5fb24c12020-06-04 11:21:33 -0500794 /**
Matt Spinler1ab66962020-10-29 13:21:44 -0500795 * @brief Get the list of system type names the system is called.
796 *
797 * @return std::vector<std::string> - The list of names
798 */
799 std::vector<std::string> getSystemNames() const override;
800
801 /**
Matt Spinler5fb24c12020-06-04 11:21:33 -0500802 * @brief Fills in the placeholder 'Ufcs' in the passed in location
803 * code with the machine feature code and serial number, which
804 * is needed to create a valid location code.
805 *
806 * @param[in] locationCode - Location code value starting with Ufcs-, and
807 * if that isn't present it will be added first.
808 *
809 * @param[in] node - The node number the location is one.
810 *
811 * @return std::string - The expanded location code
812 */
813 std::string expandLocationCode(const std::string& locationCode,
814 uint16_t node) const override;
815
816 /**
Matt Spinlerbad056b2023-01-25 14:16:57 -0600817 * @brief Returns the inventory paths for the FRU that the location
Matt Spinler5fb24c12020-06-04 11:21:33 -0500818 * code represents.
819 *
Matt Spinler2f9225a2020-08-05 12:58:49 -0500820 * @param[in] locationCode - If an expanded location code, then the
821 * full location code.
822 * If not expanded, a location code value
823 * starting with Ufcs-, and if that isn't
824 * present it will be added first.
Matt Spinler5fb24c12020-06-04 11:21:33 -0500825 *
Matt Spinler2f9225a2020-08-05 12:58:49 -0500826 * @param[in] node - The node number the location is on. Ignored if the
827 * expanded location code is passed in.
828 *
829 * @param[in] expanded - If the location code already has the relevent
830 * VPD fields embedded in it.
Matt Spinler5fb24c12020-06-04 11:21:33 -0500831 *
Matt Spinlerbad056b2023-01-25 14:16:57 -0600832 * @return std::vector<std::string> - The inventory D-Bus objects
Matt Spinler5fb24c12020-06-04 11:21:33 -0500833 */
Matt Spinlerbad056b2023-01-25 14:16:57 -0600834 std::vector<std::string>
835 getInventoryFromLocCode(const std::string& locationCode, uint16_t node,
836 bool expanded) const override;
Matt Spinler5fb24c12020-06-04 11:21:33 -0500837
Matt Spinler34a904c2020-08-05 14:53:28 -0500838 /**
Matt Spinler34a904c2020-08-05 14:53:28 -0500839 * @brief Sets the Asserted property on the LED group passed in.
840 *
841 * @param[in] ledGroup - The LED group D-Bus path
842 * @param[in] value - The value to set it to
843 */
844 void assertLEDGroup(const std::string& ledGroup, bool value) const override;
845
Matt Spinler993168d2021-04-07 16:05:03 -0500846 /**
847 * @brief Sets the Functional property on the OperationalStatus
848 * interface on a D-Bus object.
849 *
850 * @param[in] objectPath - The D-Bus object path
851 * @param[in] functional - The value
852 */
853 void setFunctional(const std::string& objectPath,
854 bool functional) const override;
855
Sumit Kumar3b8ed7f2021-05-18 12:38:35 -0500856 /**
Sumit Kumar76198a22021-07-15 05:59:57 -0500857 * @brief Sets the critical association on the D-Bus object.
858 *
859 * @param[in] objectPath - The D-Bus object path
860 */
861 void setCriticalAssociation(const std::string& objectPath) const override;
862
863 /**
Sumit Kumar3b8ed7f2021-05-18 12:38:35 -0500864 * @brief Returns the manufacturing QuiesceOnError property
865 *
866 * @return bool - Manufacturing QuiesceOnError property
867 */
868 bool getQuiesceOnError() const override;
869
Deepa Karthikeyanff35be32024-10-15 09:10:49 -0500870#ifdef PEL_ENABLE_PHAL
Sumit Kumar9d43a722021-08-24 09:46:19 -0500871 /**
Jayanth Othayothecaa2fc2021-11-05 02:02:52 -0500872 * @brief Create guard record
873 *
874 * @param[in] binPath: phal devtree binary path used as key
Deepa Karthikeyanff35be32024-10-15 09:10:49 -0500875 * @param[in] eGardType: Guard type enum value
876 * @param[in] plid: pel id to be associated to the guard record
Jayanth Othayothecaa2fc2021-11-05 02:02:52 -0500877 */
878 void createGuardRecord(const std::vector<uint8_t>& binPath,
Deepa Karthikeyanff35be32024-10-15 09:10:49 -0500879 GardType eGardType, uint32_t plid) const override;
880#endif
Jayanth Othayothecaa2fc2021-11-05 02:02:52 -0500881
Sumit Kumar3e274432021-09-14 06:37:56 -0500882 /**
883 * @brief Create Progress SRC property on the boot progress
884 * interface on a D-Bus object.
885 *
886 * @param[in] priSRC - Primary SRC value
887 * @param[in] srcStruct - Full SRC base structure
888 */
889 void
890 createProgressSRC(const uint64_t& priSRC,
891 const std::vector<uint8_t>& srcStruct) const override;
892
Sumit Kumar027bf282022-01-24 11:25:19 -0600893 /**
894 * @brief Get the list of unresolved OpenBMC event log ids that have an
895 * associated hardware isolation entry.
896 *
897 * @return std::vector<uint32_t> - The list of log ids
898 */
899 std::vector<uint32_t> getLogIDWithHwIsolation() const override;
900
Vijay Lobo875b6c72021-10-20 17:38:56 -0500901 /**
902 * @brief Returns the latest raw progress SRC from the State.Boot.Raw
903 * D-Bus interface.
904 *
905 * @return std::vector<uint8_t>: The progress SRC bytes
906 */
907 std::vector<uint8_t> getRawProgressSRC() const override;
908
Arya K Padmand8ae6182024-07-19 06:25:10 -0500909 /**
910 * @brief Returns the FRUs DI property value hosted on the VINI iterface for
911 * the given location code.
912 *
913 * @param[in] locationCode - The location code of the FRU
914 *
915 * @return std::optional<std::vector<uint8_t>> - The FRUs DI or
916 * std::nullopt
917 */
918 std::optional<std::vector<uint8_t>>
919 getDIProperty(const std::string& locationCode) const override;
920
harsh-agarwal1d763db32024-09-03 09:18:50 -0500921 /**
922 * @brief Finds all D-Bus Associated paths that contain any of the
923 * interfaces passed in, by using GetAssociatedSubTreePaths.
924 *
925 * @param[in] associatedPath - The D-Bus object path
926 * @param[in] subtree - The subtree path for which the result should be
927 * fetched
928 * @param[in] depth - The maximum subtree depth for which results should be
929 * fetched
930 * @param[in] interfaces - The desired interfaces
931 *
932 * @return The D-Bus paths.
933 */
934 DBusPathList getAssociatedPaths(
935 const DBusPath& associatedPath, const DBusPath& subtree, int32_t depth,
936 const DBusInterfaceList& interfaces) const override;
937
Matt Spinler2a28c932020-02-03 14:23:40 -0600938 private:
939 /**
940 * @brief Reads the BMC firmware version string and puts it into
941 * _bmcFWVersion.
942 */
943 void readBMCFWVersion();
Matt Spinlera7d9d962019-11-06 15:01:25 -0600944
945 /**
Matt Spinler2a28c932020-02-03 14:23:40 -0600946 * @brief Reads the server firmware version string and puts it into
947 * _serverFWVersion.
Matt Spinlerc8705e22019-09-11 12:36:07 -0500948 */
Matt Spinler2a28c932020-02-03 14:23:40 -0600949 void readServerFWVersion();
Matt Spinlerc8705e22019-09-11 12:36:07 -0500950
951 /**
Matt Spinler2a28c932020-02-03 14:23:40 -0600952 * @brief Reads the BMC firmware version ID and puts it into
953 * _bmcFWVersionID.
Matt Spinlera7d9d962019-11-06 15:01:25 -0600954 */
Matt Spinler2a28c932020-02-03 14:23:40 -0600955 void readBMCFWVersionID();
Matt Spinlera7d9d962019-11-06 15:01:25 -0600956
957 /**
Matt Spinlerb3d488f2020-02-21 15:30:46 -0600958 * @brief Finds all D-Bus paths that contain any of the interfaces
959 * passed in, by using GetSubTreePaths.
960 *
961 * @param[in] interfaces - The desired interfaces
962 *
963 * @return The D-Bus paths.
964 */
965 DBusPathList getPaths(const DBusInterfaceList& interfaces) const;
966
967 /**
968 * @brief The interfacesAdded callback used on the inventory to
969 * find the D-Bus object that has the motherboard interface.
970 * When the motherboard is found, it then adds a PropertyWatcher
971 * for the motherboard CCIN.
972 */
Patrick Williams45e83522022-07-22 19:26:52 -0500973 void motherboardIfaceAdded(sdbusplus::message_t& msg);
Matt Spinlerb3d488f2020-02-21 15:30:46 -0600974
975 /**
Matt Spinler5b423652023-05-04 13:08:44 -0500976 * @brief Start watching for the hotpluggable FRUs to become
977 * present.
978 */
979 void startFruPlugWatch();
980
981 /**
982 * @brief Create a D-Bus match object for the Present property
983 * to change on the path passed in.
984 * @param[in] path - The path to watch.
985 */
986 void addHotplugWatch(const std::string& path);
987
988 /**
989 * @brief Callback when an inventory interface was added.
990 *
991 * Only does something if it's one of the hotpluggable FRUs,
992 * in which case it will treat it as a hotplug if the
993 * Present property is true.
994 *
995 * @param[in] msg - The InterfacesAdded signal contents.
996 */
997 void inventoryIfaceAdded(sdbusplus::message_t& msg);
998
999 /**
1000 * @brief Callback when the Present property changes.
1001 *
1002 * If present, will run the registered callbacks.
1003 *
1004 * @param[in] msg - The PropertiesChanged signal contents.
1005 */
1006 void presenceChanged(sdbusplus::message_t& msg);
1007
1008 /**
1009 * @brief If the Present property is in the properties map
1010 * passed in and it is true, notify the subscribers.
1011 *
1012 * @param[in] path - The object path of the inventory item.
1013 * @param[in] properties - The properties map
1014 */
1015 void notifyPresenceSubsribers(const std::string& path,
1016 const DBusPropertyMap& properties);
1017
1018 /**
Matt Spinler0e4d72e2020-08-05 12:36:53 -05001019 * @brief Adds the Ufcs- prefix to the location code passed in
1020 * if necessary.
Matt Spinler5fb24c12020-06-04 11:21:33 -05001021 *
Matt Spinler0e4d72e2020-08-05 12:36:53 -05001022 * Needed because the location codes that come back from the
Matt Spinler5fb24c12020-06-04 11:21:33 -05001023 * message registry and device callout JSON don't have it.
1024 *
1025 * @param[in] - The location code without a prefix, like P1-C1
1026 *
1027 * @return std::string - The location code with the prefix
1028 */
1029 static std::string addLocationCodePrefix(const std::string& locationCode);
1030
Arya K Padmanafba3162024-08-30 07:41:32 -05001031 /**
1032 * @brief A helper API to check whether the PHAL device tree is exists,
1033 * ensuring the PHAL init API can be invoked.
1034 *
1035 * @return true if the PHAL device tree is exists, otherwise false
1036 */
1037 bool isPHALDevTreeExist() const;
1038
Arya K Padman0b758fb2024-09-06 11:59:45 -05001039#ifdef PEL_ENABLE_PHAL
Arya K Padmanafba3162024-08-30 07:41:32 -05001040 /**
1041 * @brief A helper API to init PHAL libraries
1042 *
1043 * @return None
1044 */
1045 void initPHAL();
Arya K Padman0b758fb2024-09-06 11:59:45 -05001046#endif // PEL_ENABLE_PHAL
Arya K Padmanafba3162024-08-30 07:41:32 -05001047
1048 /**
1049 * @brief A helper API to subscribe to systemd signals
1050 *
1051 * @return None
1052 */
1053 void subscribeToSystemdSignals();
1054
1055 /**
1056 * @brief A helper API to unsubscribe to systemd signals
1057 *
1058 * @return None
1059 */
1060 void unsubscribeFromSystemdSignals();
Arya K Padmanafba3162024-08-30 07:41:32 -05001061
Matt Spinler5fb24c12020-06-04 11:21:33 -05001062 /**
Matt Spinler2a28c932020-02-03 14:23:40 -06001063 * @brief The D-Bus property or interface watchers that have callbacks
1064 * registered that will set members in this class when
1065 * they change.
Matt Spinlerc8705e22019-09-11 12:36:07 -05001066 */
Matt Spinler2a28c932020-02-03 14:23:40 -06001067 std::vector<std::unique_ptr<DBusWatcher>> _properties;
Matt Spinlera7d9d962019-11-06 15:01:25 -06001068
Matt Spinler5b423652023-05-04 13:08:44 -05001069 std::unique_ptr<sdbusplus::bus::match_t> _invIaMatch;
1070
1071 /**
1072 * @brief The matches for watching for hotplugs.
1073 *
1074 * A map so we can check that we never get duplicates.
1075 */
1076 std::map<std::string, std::unique_ptr<sdbusplus::bus::match_t>>
1077 _invPresentMatches;
1078
Matt Spinlera7d9d962019-11-06 15:01:25 -06001079 /**
Matt Spinlerc8705e22019-09-11 12:36:07 -05001080 * @brief The sdbusplus bus object for making D-Bus calls.
1081 */
Patrick Williams45e83522022-07-22 19:26:52 -05001082 sdbusplus::bus_t& _bus;
Arya K Padmanafba3162024-08-30 07:41:32 -05001083
Arya K Padmanafba3162024-08-30 07:41:32 -05001084 /**
1085 * @brief Watcher to check "openpower-update-bios-attr-table" service
1086 * is "done" to init PHAL libraires
1087 */
1088 std::unique_ptr<sdbusplus::bus::match_t> _systemdMatch;
Arya K Padmanafba3162024-08-30 07:41:32 -05001089
1090 /**
1091 * @brief A slot object for async dbus call
1092 */
1093 sdbusplus::slot_t _systemdSlot;
Matt Spinlerc8705e22019-09-11 12:36:07 -05001094};
1095
1096} // namespace pels
1097} // namespace openpower