blob: c6cfe4e822815de5b11907ccdea0025d56ce56a9 [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
Matt Spinlera167a7d2023-06-30 15:14:25 -05006#include <phosphor-logging/lg2.hpp>
Matt Spinlerc8705e22019-09-11 12:36:07 -05007#include <sdbusplus/bus.hpp>
8#include <sdbusplus/bus/match.hpp>
9
Arya K Padmand8ae6182024-07-19 06:25:10 -050010#include <expected>
Patrick Williams2544b412022-10-04 08:41:06 -050011#include <filesystem>
12#include <fstream>
Arya K Padmand8ae6182024-07-19 06:25:10 -050013#include <unordered_map>
Patrick Williams2544b412022-10-04 08:41:06 -050014
Matt Spinlerc8705e22019-09-11 12:36:07 -050015namespace openpower
16{
17namespace pels
18{
19
Matt Spinlerc8705e22019-09-11 12:36:07 -050020/**
21 * @class DataInterface
22 *
Matt Spinler19e89ce2019-11-06 13:02:23 -060023 * A base class for gathering data about the system for use
24 * in PELs. Implemented this way to facilitate mocking.
Matt Spinlerc8705e22019-09-11 12:36:07 -050025 */
26class DataInterfaceBase
27{
28 public:
29 DataInterfaceBase() = default;
30 virtual ~DataInterfaceBase() = default;
31 DataInterfaceBase(const DataInterfaceBase&) = default;
32 DataInterfaceBase& operator=(const DataInterfaceBase&) = default;
33 DataInterfaceBase(DataInterfaceBase&&) = default;
34 DataInterfaceBase& operator=(DataInterfaceBase&&) = default;
35
36 /**
Matt Spinler19e89ce2019-11-06 13:02:23 -060037 * @brief Returns the machine Type/Model
Matt Spinlerc8705e22019-09-11 12:36:07 -050038 *
39 * @return string - The machine Type/Model string
40 */
Vijay Lobo81b4dca2021-04-29 00:04:00 -050041 virtual std::string getMachineTypeModel() const = 0;
Matt Spinlerc8705e22019-09-11 12:36:07 -050042
43 /**
Matt Spinler19e89ce2019-11-06 13:02:23 -060044 * @brief Returns the machine serial number
Matt Spinlerc8705e22019-09-11 12:36:07 -050045 *
46 * @return string - The machine serial number
47 */
Vijay Lobo81b4dca2021-04-29 00:04:00 -050048 virtual std::string getMachineSerialNumber() const = 0;
Matt Spinler19e89ce2019-11-06 13:02:23 -060049
Matt Spinlera7d9d962019-11-06 15:01:25 -060050 /**
Matt Spinlercce14112019-12-11 14:20:36 -060051 * @brief Says if the system is managed by a hardware
52 * management console.
53 * @return bool - If the system is HMC managed
54 */
55 virtual bool isHMCManaged() const
56 {
57 return _hmcManaged;
58 }
59
60 /**
Matt Spinlera7d9d962019-11-06 15:01:25 -060061 * @brief Says if the host is up and running
62 *
63 * @return bool - If the host is running
64 */
65 virtual bool isHostUp() const
66 {
67 return _hostUp;
68 }
69
70 using HostStateChangeFunc = std::function<void(bool)>;
71
72 /**
73 * @brief Register a callback function that will get
74 * called on all host on/off transitions.
75 *
76 * The void(bool) function will get passed the new
77 * value of the host state.
78 *
79 * @param[in] name - The subscription name
80 * @param[in] func - The function to run
81 */
82 void subscribeToHostStateChange(const std::string& name,
83 HostStateChangeFunc func)
84 {
85 _hostChangeCallbacks[name] = func;
86 }
87
88 /**
89 * @brief Unsubscribe from host state changes.
90 *
91 * @param[in] name - The subscription name
92 */
93 void unsubscribeFromHostStateChange(const std::string& name)
94 {
95 _hostChangeCallbacks.erase(name);
96 }
97
Matt Spinler5b423652023-05-04 13:08:44 -050098 using FRUPresentFunc =
99 std::function<void(const std::string& /* locationCode */)>;
100
101 /**
102 * @brief Register a callback function that will get
103 * called when certain FRUs become present.
104 *
105 * The void(std::string) function will get passed the
106 * location code of the FRU.
107 *
108 * @param[in] name - The subscription name
109 * @param[in] func - The function to run
110 */
111 void subscribeToFruPresent(const std::string& name, FRUPresentFunc func)
112 {
113 _fruPresentCallbacks[name] = std::move(func);
114 }
115
Matt Spinlercad9c2b2019-12-02 15:42:01 -0600116 /**
117 * @brief Returns the BMC firmware version
118 *
119 * @return std::string - The BMC version
120 */
121 virtual std::string getBMCFWVersion() const
122 {
123 return _bmcFWVersion;
124 }
125
126 /**
127 * @brief Returns the server firmware version
128 *
129 * @return std::string - The server firmware version
130 */
131 virtual std::string getServerFWVersion() const
132 {
133 return _serverFWVersion;
134 }
135
Matt Spinler4dcd3f42020-01-22 14:55:07 -0600136 /**
Matt Spinler677381b2020-01-23 10:04:29 -0600137 * @brief Returns the BMC FW version ID
138 *
139 * @return std::string - The BMC FW version ID
140 */
141 virtual std::string getBMCFWVersionID() const
142 {
143 return _bmcFWVersionID;
144 }
145
146 /**
Matt Spinler4dcd3f42020-01-22 14:55:07 -0600147 * @brief Returns the process name given its PID.
148 *
149 * @param[in] pid - The PID value as a string
150 *
151 * @return std::optional<std::string> - The name, or std::nullopt
152 */
153 std::optional<std::string> getProcessName(const std::string& pid) const
154 {
155 namespace fs = std::filesystem;
156
157 fs::path path{"/proc"};
158 path /= fs::path{pid} / "exe";
159
160 if (fs::exists(path))
161 {
162 return fs::read_symlink(path);
163 }
164
165 return std::nullopt;
166 }
167
Matt Spinler9cf3cfd2020-02-03 14:41:55 -0600168 /**
George Liu9ac0d9b2022-07-15 10:57:38 +0800169 * @brief Returns the time the system was running.
170 *
171 * @return std::optional<uint64_t> - The System uptime or std::nullopt
172 */
173 std::optional<uint64_t> getUptimeInSeconds() const
174 {
175 std::ifstream versionFile{"/proc/uptime"};
176 std::string line{};
177
178 std::getline(versionFile, line);
179 auto pos = line.find(" ");
180 if (pos == std::string::npos)
181 {
182 return std::nullopt;
183 }
184
185 uint64_t seconds = atol(line.substr(0, pos).c_str());
186 if (seconds == 0)
187 {
188 return std::nullopt;
189 }
190
191 return seconds;
192 }
193
194 /**
195 * @brief Returns the time the system was running.
196 *
197 * @param[in] seconds - The number of seconds the system has been running
198 *
199 * @return std::string - days/hours/minutes/seconds
200 */
201 std::string getBMCUptime(uint64_t seconds) const
202 {
203 time_t t(seconds);
204 tm* p = gmtime(&t);
205
Patrick Williams075c7922024-08-16 15:19:49 -0400206 std::string uptime =
207 std::to_string(p->tm_year - 70) + "y " +
208 std::to_string(p->tm_yday) + "d " + std::to_string(p->tm_hour) +
209 "h " + std::to_string(p->tm_min) + "m " +
210 std::to_string(p->tm_sec) + "s";
George Liu9ac0d9b2022-07-15 10:57:38 +0800211
212 return uptime;
213 }
214
215 /**
216 * @brief Returns the system load average over the past 1 minute, 5 minutes
217 * and 15 minutes.
218 *
219 * @return std::string - The system load average
220 */
221 std::string getBMCLoadAvg() const
222 {
223 std::string loadavg{};
224
225 std::ifstream loadavgFile{"/proc/loadavg"};
226 std::string line;
227 std::getline(loadavgFile, line);
228
229 size_t count = 3;
230 for (size_t i = 0; i < count; i++)
231 {
232 auto pos = line.find(" ");
233 if (pos == std::string::npos)
234 {
235 return {};
236 }
237
238 if (i != count - 1)
239 {
240 loadavg.append(line.substr(0, pos + 1));
241 }
242 else
243 {
244 loadavg.append(line.substr(0, pos));
245 }
246
247 line = line.substr(pos + 1);
248 }
249
250 return loadavg;
251 }
252
253 /**
Matt Spinler9cf3cfd2020-02-03 14:41:55 -0600254 * @brief Returns the 'send event logs to host' setting.
255 *
256 * @return bool - If sending PELs to the host is enabled.
257 */
258 virtual bool getHostPELEnablement() const
259 {
260 return _sendPELsToHost;
261 }
262
Matt Spinler4aa23a12020-02-03 15:05:09 -0600263 /**
264 * @brief Returns the BMC state
265 *
266 * @return std::string - The BMC state property value
267 */
268 virtual std::string getBMCState() const
269 {
270 return _bmcState;
271 }
272
273 /**
274 * @brief Returns the Chassis state
275 *
276 * @return std::string - The chassis state property value
277 */
278 virtual std::string getChassisState() const
279 {
280 return _chassisState;
281 }
282
283 /**
284 * @brief Returns the chassis requested power
285 * transition value.
286 *
287 * @return std::string - The chassis transition property
288 */
289 virtual std::string getChassisTransition() const
290 {
291 return _chassisTransition;
292 }
293
294 /**
295 * @brief Returns the Host state
296 *
297 * @return std::string - The Host state property value
298 */
299 virtual std::string getHostState() const
300 {
301 return _hostState;
302 }
303
Matt Spinlerb3d488f2020-02-21 15:30:46 -0600304 /**
Sumit Kumar2c36fdd2021-09-21 03:12:11 -0500305 * @brief Returns the Boot state
306 *
307 * @return std::string - The Boot state property value
308 */
309 virtual std::string getBootState() const
310 {
311 return _bootState;
312 }
313
314 /**
Matt Spinlerb3d488f2020-02-21 15:30:46 -0600315 * @brief Returns the motherboard CCIN
316 *
317 * @return std::string The motherboard CCIN
318 */
Vijay Lobo81b4dca2021-04-29 00:04:00 -0500319 virtual std::string getMotherboardCCIN() const = 0;
Matt Spinlerb3d488f2020-02-21 15:30:46 -0600320
Matt Spinler60c4e792020-03-13 13:45:36 -0500321 /**
Ben Tynere32b7e72021-05-18 12:38:40 -0500322 * @brief Returns the system IM
323 *
324 * @return std::string The system IM
325 */
326 virtual std::vector<uint8_t> getSystemIMKeyword() const = 0;
327
328 /**
Matt Spinler60c4e792020-03-13 13:45:36 -0500329 * @brief Get the fields from the inventory necessary for doing
330 * a callout on an inventory path.
331 *
332 * @param[in] inventoryPath - The item to get the data for
Matt Spinler60c4e792020-03-13 13:45:36 -0500333 * @param[out] fruPartNumber - Filled in with the VINI/FN keyword
334 * @param[out] ccin - Filled in with the VINI/CC keyword
335 * @param[out] serialNumber - Filled in with the VINI/SN keyword
336 */
Patrick Williams075c7922024-08-16 15:19:49 -0400337 virtual void getHWCalloutFields(
338 const std::string& inventoryPath, std::string& fruPartNumber,
339 std::string& ccin, std::string& serialNumber) const = 0;
Matt Spinler60c4e792020-03-13 13:45:36 -0500340
Matt Spinler03984582020-04-09 13:17:58 -0500341 /**
Matt Spinler9b90e2a2020-04-14 10:59:04 -0500342 * @brief Get the location code for an inventory item.
343 *
344 * @param[in] inventoryPath - The item to get the data for
345 *
346 * @return std::string - The location code
347 */
348 virtual std::string
349 getLocationCode(const std::string& inventoryPath) const = 0;
350
351 /**
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500352 * @brief Get the list of system type names the system is called.
Matt Spinler03984582020-04-09 13:17:58 -0500353 *
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500354 * @return std::vector<std::string> - The list of names
Matt Spinler03984582020-04-09 13:17:58 -0500355 */
Matt Spinler1ab66962020-10-29 13:21:44 -0500356 virtual std::vector<std::string> getSystemNames() const = 0;
Matt Spinler03984582020-04-09 13:17:58 -0500357
Matt Spinler5fb24c12020-06-04 11:21:33 -0500358 /**
359 * @brief Fills in the placeholder 'Ufcs' in the passed in location
360 * code with the machine feature code and serial number, which
361 * is needed to create a valid location code.
362 *
363 * @param[in] locationCode - Location code value starting with Ufcs-, and
364 * if that isn't present it will be added first.
365 *
366 * @param[in] node - The node number the location is on.
367 *
368 * @return std::string - The expanded location code
369 */
370 virtual std::string expandLocationCode(const std::string& locationCode,
371 uint16_t node) const = 0;
372
373 /**
Matt Spinlerbad056b2023-01-25 14:16:57 -0600374 * @brief Returns the inventory paths for the FRU that the location
Matt Spinler5fb24c12020-06-04 11:21:33 -0500375 * code represents.
376 *
Matt Spinler2f9225a2020-08-05 12:58:49 -0500377 * @param[in] locationCode - If an expanded location code, then the
378 * full location code.
379 * If not expanded, a location code value
380 * starting with Ufcs-, and if that isn't
381 * present it will be added first.
Matt Spinler5fb24c12020-06-04 11:21:33 -0500382 *
Matt Spinler2f9225a2020-08-05 12:58:49 -0500383 * @param[in] node - The node number the location is on. Ignored if the
384 * expanded location code is passed in.
385 *
386 * @param[in] expanded - If the location code already has the relevent
387 * VPD fields embedded in it.
Matt Spinler5fb24c12020-06-04 11:21:33 -0500388 *
Matt Spinlerbad056b2023-01-25 14:16:57 -0600389 * @return std::vector<std::string> - The inventory D-Bus objects
Matt Spinler5fb24c12020-06-04 11:21:33 -0500390 */
Matt Spinlerbad056b2023-01-25 14:16:57 -0600391 virtual std::vector<std::string>
392 getInventoryFromLocCode(const std::string& LocationCode, uint16_t node,
393 bool expanded) const = 0;
Matt Spinler5fb24c12020-06-04 11:21:33 -0500394
Matt Spinler34a904c2020-08-05 14:53:28 -0500395 /**
Matt Spinler34a904c2020-08-05 14:53:28 -0500396 * @brief Sets the Asserted property on the LED group passed in.
397 *
398 * @param[in] ledGroup - The LED group D-Bus path
399 * @param[in] value - The value to set it to
400 */
401 virtual void assertLEDGroup(const std::string& ledGroup,
402 bool value) const = 0;
403
Matt Spinler993168d2021-04-07 16:05:03 -0500404 /**
405 * @brief Sets the Functional property on the OperationalStatus
406 * interface on a D-Bus object.
407 *
408 * @param[in] objectPath - The D-Bus object path
409 * @param[in] functional - The value
410 */
411 virtual void setFunctional(const std::string& objectPath,
412 bool functional) const = 0;
413
Sumit Kumar3b8ed7f2021-05-18 12:38:35 -0500414 /**
Sumit Kumar76198a22021-07-15 05:59:57 -0500415 * @brief Sets the critical association on the D-Bus object.
416 *
417 * @param[in] objectPath - The D-Bus object path
418 */
419 virtual void
420 setCriticalAssociation(const std::string& objectPath) const = 0;
421
422 /**
Sumit Kumar3b8ed7f2021-05-18 12:38:35 -0500423 * @brief Returns the manufacturing QuiesceOnError property
424 *
425 * @return bool - Manufacturing QuiesceOnError property
426 */
427 virtual bool getQuiesceOnError() const = 0;
428
Matt Spinler0d92b522021-06-16 13:28:17 -0600429 /**
430 * @brief Split location code into base and connector segments
431 *
432 * A location code that ends in '-Tx', where 'x' is a number,
433 * represents a connector, such as a USB cable connector.
434 *
435 * This function splits the passed in location code into a
436 * base and connector segment. e.g.:
437 * P0-T1 -> ['P0', '-T1']
438 * P0 -> ['P0', '']
439 *
440 * @param[in] locationCode - location code to split
441 * @return pair<string, string> - The base and connector segments
442 */
443 static std::pair<std::string, std::string>
444 extractConnectorFromLocCode(const std::string& locationCode);
445
Sumit Kumar9d43a722021-08-24 09:46:19 -0500446 /**
447 * @brief Returns the dump status
448 *
449 * @return bool dump status
450 */
451 virtual std::vector<bool>
452 checkDumpStatus(const std::vector<std::string>& type) const = 0;
453
Jayanth Othayothecaa2fc2021-11-05 02:02:52 -0500454 /**
455 * @brief Create guard record
456 *
457 * @param[in] binPath: phal devtree binary path used as key
458 * @param[in] type: Guard type
459 * @param[in] logPath: error log entry object path
460 */
461 virtual void createGuardRecord(const std::vector<uint8_t>& binPath,
462 const std::string& type,
463 const std::string& logPath) const = 0;
464
Sumit Kumar3e274432021-09-14 06:37:56 -0500465 /**
466 * @brief Create Progress SRC property on the boot progress
467 * interface on a D-Bus object.
468 *
469 * @param[in] priSRC - Primary SRC value (e.g. BD8D1001)
470 * @param[in] srcStruct - Full SRC base structure
471 */
472 virtual void
473 createProgressSRC(const uint64_t& priSRC,
474 const std::vector<uint8_t>& srcStruct) const = 0;
475
Sumit Kumar027bf282022-01-24 11:25:19 -0600476 /**
477 * @brief Get the list of unresolved OpenBMC event log ids that have an
478 * associated hardware isolation entry.
479 *
480 * @return std::vector<uint32_t> - The list of log ids
481 */
482 virtual std::vector<uint32_t> getLogIDWithHwIsolation() const = 0;
483
Vijay Lobo875b6c72021-10-20 17:38:56 -0500484 /**
485 * @brief Returns the latest raw progress SRC from the State.Boot.Raw
486 * D-Bus interface.
487 *
488 * @return std::vector<uint8_t> - The progress SRC bytes
489 */
490 virtual std::vector<uint8_t> getRawProgressSRC() const = 0;
491
Arya K Padmand8ae6182024-07-19 06:25:10 -0500492 /**
493 * @brief Returns the FRUs DI property value hosted on the VINI iterface for
494 * the given location code.
495 *
496 * @param[in] locationCode - The location code of the FRU
497 *
498 * @return std::optional<std::vector<uint8_t>> - The FRUs DI or
499 * std::nullopt
500 */
501 virtual std::optional<std::vector<uint8_t>>
502 getDIProperty(const std::string& locationCode) const = 0;
503
504 /**
505 * @brief Wrpper API to call pHAL API 'getFRUType()' and check whether the
506 * given location code is DIMM or not
507 *
508 * @param[in] locCode - The location code of the FRU
509 *
Arya K Padmanced8ed72024-09-02 05:18:07 -0500510 * @return - true, if the given location code is DIMM
511 * - false, if the given location code is not DIMM or if it fails to
512 * determine the FRU type.
Arya K Padmand8ae6182024-07-19 06:25:10 -0500513 */
Arya K Padmanced8ed72024-09-02 05:18:07 -0500514 bool isDIMM(const std::string& locCode);
Arya K Padmand8ae6182024-07-19 06:25:10 -0500515
516 /**
517 * @brief Check whether the given location code present in the cache
518 * memory
519 *
520 * @param[in] locCode - The location code of the FRU
521 *
522 * @return true, if the given location code present in cache and is a DIMM
523 * false, if the given location code present in cache, but a non
524 * DIMM FRU
525 * std::nullopt, if the given location code is not present in the
526 * cache.
527 */
528 std::optional<bool> isDIMMLocCode(const std::string& locCode) const;
529
530 /**
531 * @brief add the given location code to the cache memory
532 *
533 * @param[in] locCode - The location code of the FRU
534 * @param[in] isFRUDIMM - true indicates the FRU is a DIMM
535 * false indicates the FRU is a non DIMM
536 *
537 */
538 void addDIMMLocCode(const std::string& locCode, bool isFRUDIMM);
539
harsh-agarwal1d763db32024-09-03 09:18:50 -0500540 /**
541 * @brief Finds all D-Bus Associated paths that contain any of the
542 * interfaces passed in, by using GetAssociatedSubTreePaths.
543 *
544 * @param[in] associatedPath - The D-Bus object path
545 * @param[in] subtree - The subtree path for which the result should be
546 * fetched
547 * @param[in] depth - The maximum subtree depth for which results should be
548 * fetched
549 * @param[in] interfaces - The desired interfaces
550 *
551 * @return The D-Bus paths.
552 */
553 virtual DBusPathList getAssociatedPaths(
554 const DBusPath& associatedPath, const DBusPath& subtree, int32_t depth,
555 const DBusInterfaceList& interfaces) const = 0;
556
Matt Spinler19e89ce2019-11-06 13:02:23 -0600557 protected:
558 /**
Matt Spinlera7d9d962019-11-06 15:01:25 -0600559 * @brief Sets the host on/off state and runs any
560 * callback functions (if there was a change).
561 */
Matt Spinler4aa23a12020-02-03 15:05:09 -0600562 void setHostUp(bool hostUp)
Matt Spinlera7d9d962019-11-06 15:01:25 -0600563 {
Matt Spinler4aa23a12020-02-03 15:05:09 -0600564 if (_hostUp != hostUp)
Matt Spinlera7d9d962019-11-06 15:01:25 -0600565 {
Matt Spinler4aa23a12020-02-03 15:05:09 -0600566 _hostUp = hostUp;
Matt Spinlera7d9d962019-11-06 15:01:25 -0600567
568 for (auto& [name, func] : _hostChangeCallbacks)
569 {
570 try
571 {
572 func(_hostUp);
573 }
Patrick Williams66491c62021-10-06 12:23:37 -0500574 catch (const std::exception& e)
Matt Spinlera7d9d962019-11-06 15:01:25 -0600575 {
Matt Spinlera167a7d2023-06-30 15:14:25 -0500576 lg2::error(
577 "A host state change callback threw an exception");
Matt Spinlera7d9d962019-11-06 15:01:25 -0600578 }
579 }
580 }
581 }
582
583 /**
Matt Spinler5b423652023-05-04 13:08:44 -0500584 * @brief Runs the callback functions registered when
585 * FRUs become present.
586 */
587 void setFruPresent(const std::string& locationCode)
588 {
589 for (const auto& [_, func] : _fruPresentCallbacks)
590 {
591 try
592 {
593 func(locationCode);
594 }
595 catch (const std::exception& e)
596 {
Matt Spinlera167a7d2023-06-30 15:14:25 -0500597 lg2::error("A FRU present callback threw an exception");
Matt Spinler5b423652023-05-04 13:08:44 -0500598 }
599 }
600 }
601
602 /**
Matt Spinlercce14112019-12-11 14:20:36 -0600603 * @brief The hardware management console status. Always kept
604 * up to date.
605 */
606 bool _hmcManaged = false;
607
608 /**
Matt Spinlera7d9d962019-11-06 15:01:25 -0600609 * @brief The host up status. Always kept up to date.
610 */
611 bool _hostUp = false;
612
613 /**
614 * @brief The map of host state change subscriber
615 * names to callback functions.
616 */
617 std::map<std::string, HostStateChangeFunc> _hostChangeCallbacks;
Matt Spinlercad9c2b2019-12-02 15:42:01 -0600618
619 /**
Matt Spinler5b423652023-05-04 13:08:44 -0500620 * @brief The map of FRU present subscriber
621 * names to callback functions.
622 */
623 std::map<std::string, FRUPresentFunc> _fruPresentCallbacks;
624
625 /**
Matt Spinlercad9c2b2019-12-02 15:42:01 -0600626 * @brief The BMC firmware version string
627 */
628 std::string _bmcFWVersion;
629
630 /**
631 * @brief The server firmware version string
632 */
633 std::string _serverFWVersion;
Matt Spinler677381b2020-01-23 10:04:29 -0600634
635 /**
636 * @brief The BMC firmware version ID string
637 */
638 std::string _bmcFWVersionID;
Matt Spinler9cf3cfd2020-02-03 14:41:55 -0600639
640 /**
641 * @brief If sending PELs is enabled.
642 *
643 * This is usually set to false in manufacturing test.
644 */
645 bool _sendPELsToHost = true;
Matt Spinler4aa23a12020-02-03 15:05:09 -0600646
647 /**
648 * @brief The BMC state property
649 */
650 std::string _bmcState;
651
652 /**
653 * @brief The Chassis current power state property
654 */
655 std::string _chassisState;
656
657 /**
658 * @brief The Chassis requested power transition property
659 */
660 std::string _chassisTransition;
661
662 /**
663 * @brief The host state property
664 */
665 std::string _hostState;
Sumit Kumar2c36fdd2021-09-21 03:12:11 -0500666
667 /**
668 * @brief The boot state property
669 */
670 std::string _bootState;
Arya K Padmand8ae6182024-07-19 06:25:10 -0500671
672 /**
673 * @brief A cache storage for location code and its FRU Type
674 * - The key 'std::string' represents the locationCode of the FRU
675 * - The bool value - true indicates the FRU is a DIMM
676 * false indicates the FRU is a non DIMM.
677 */
678 std::unordered_map<std::string, bool> _locationCache;
Matt Spinlerc8705e22019-09-11 12:36:07 -0500679};
680
681/**
682 * @class DataInterface
683 *
684 * Concrete implementation of DataInterfaceBase.
685 */
686class DataInterface : public DataInterfaceBase
687{
688 public:
689 DataInterface() = delete;
690 ~DataInterface() = default;
691 DataInterface(const DataInterface&) = default;
692 DataInterface& operator=(const DataInterface&) = default;
693 DataInterface(DataInterface&&) = default;
694 DataInterface& operator=(DataInterface&&) = default;
695
696 /**
697 * @brief Constructor
698 *
699 * @param[in] bus - The sdbusplus bus object
700 */
Patrick Williams45e83522022-07-22 19:26:52 -0500701 explicit DataInterface(sdbusplus::bus_t& bus);
Matt Spinlerc8705e22019-09-11 12:36:07 -0500702
Matt Spinlerb3f51862019-12-09 13:55:10 -0600703 /**
Matt Spinlerc8705e22019-09-11 12:36:07 -0500704 * @brief Finds the D-Bus service name that hosts the
705 * passed in path and interface.
706 *
707 * @param[in] objectPath - The D-Bus object path
708 * @param[in] interface - The D-Bus interface
709 */
710 DBusService getService(const std::string& objectPath,
Matt Spinlerb3f51862019-12-09 13:55:10 -0600711 const std::string& interface) const;
Matt Spinler9cf3cfd2020-02-03 14:41:55 -0600712
Matt Spinlerc8705e22019-09-11 12:36:07 -0500713 /**
714 * @brief Wrapper for the 'GetAll' properties method call
715 *
716 * @param[in] service - The D-Bus service to call it on
717 * @param[in] objectPath - The D-Bus object path
718 * @param[in] interface - The interface to get the props on
719 *
720 * @return DBusPropertyMap - The property results
721 */
722 DBusPropertyMap getAllProperties(const std::string& service,
723 const std::string& objectPath,
Matt Spinler2a28c932020-02-03 14:23:40 -0600724 const std::string& interface) const;
Matt Spinlerc8705e22019-09-11 12:36:07 -0500725 /**
Matt Spinlera7d9d962019-11-06 15:01:25 -0600726 * @brief Wrapper for the 'Get' properties method call
727 *
728 * @param[in] service - The D-Bus service to call it on
729 * @param[in] objectPath - The D-Bus object path
730 * @param[in] interface - The interface to get the property on
731 * @param[in] property - The property name
732 * @param[out] value - Filled in with the property value.
733 */
734 void getProperty(const std::string& service, const std::string& objectPath,
735 const std::string& interface, const std::string& property,
Matt Spinler2a28c932020-02-03 14:23:40 -0600736 DBusValue& value) const;
Vijay Lobo81b4dca2021-04-29 00:04:00 -0500737 /**
738 * @brief Returns the machine Type/Model
739 *
740 * @return string - The machine Type/Model string
741 */
742 std::string getMachineTypeModel() const override;
743
744 /**
745 * @brief Returns the machine serial number
746 *
747 * @return string - The machine serial number
748 */
749 std::string getMachineSerialNumber() const override;
750
751 /**
752 * @brief Returns the motherboard CCIN
753 *
754 * @return std::string The motherboard CCIN
755 */
756 std::string getMotherboardCCIN() const override;
Matt Spinler2a28c932020-02-03 14:23:40 -0600757
Matt Spinler60c4e792020-03-13 13:45:36 -0500758 /**
Ben Tynere32b7e72021-05-18 12:38:40 -0500759 * @brief Returns the system IM
760 *
761 * @return std::vector The system IM keyword in 4 byte vector
762 */
763 std::vector<uint8_t> getSystemIMKeyword() const override;
764
765 /**
Matt Spinler60c4e792020-03-13 13:45:36 -0500766 * @brief Get the fields from the inventory necessary for doing
767 * a callout on an inventory path.
768 *
769 * @param[in] inventoryPath - The item to get the data for
Matt Spinler60c4e792020-03-13 13:45:36 -0500770 * @param[out] fruPartNumber - Filled in with the VINI/FN keyword
771 * @param[out] ccin - Filled in with the VINI/CC keyword
772 * @param[out] serialNumber - Filled in with the VINI/SN keyword
773 */
774 void getHWCalloutFields(const std::string& inventoryPath,
Matt Spinler60c4e792020-03-13 13:45:36 -0500775 std::string& fruPartNumber, std::string& ccin,
776 std::string& serialNumber) const override;
777
Matt Spinler9b90e2a2020-04-14 10:59:04 -0500778 /**
779 * @brief Get the location code for an inventory item.
780 *
781 * Throws an exception if the inventory item doesn't have the
782 * location code interface.
783 *
784 * @param[in] inventoryPath - The item to get the data for
785 *
786 * @return std::string - The location code
787 */
788 std::string
789 getLocationCode(const std::string& inventoryPath) const override;
790
Matt Spinler5fb24c12020-06-04 11:21:33 -0500791 /**
Matt Spinler1ab66962020-10-29 13:21:44 -0500792 * @brief Get the list of system type names the system is called.
793 *
794 * @return std::vector<std::string> - The list of names
795 */
796 std::vector<std::string> getSystemNames() const override;
797
798 /**
Matt Spinler5fb24c12020-06-04 11:21:33 -0500799 * @brief Fills in the placeholder 'Ufcs' in the passed in location
800 * code with the machine feature code and serial number, which
801 * is needed to create a valid location code.
802 *
803 * @param[in] locationCode - Location code value starting with Ufcs-, and
804 * if that isn't present it will be added first.
805 *
806 * @param[in] node - The node number the location is one.
807 *
808 * @return std::string - The expanded location code
809 */
810 std::string expandLocationCode(const std::string& locationCode,
811 uint16_t node) const override;
812
813 /**
Matt Spinlerbad056b2023-01-25 14:16:57 -0600814 * @brief Returns the inventory paths for the FRU that the location
Matt Spinler5fb24c12020-06-04 11:21:33 -0500815 * code represents.
816 *
Matt Spinler2f9225a2020-08-05 12:58:49 -0500817 * @param[in] locationCode - If an expanded location code, then the
818 * full location code.
819 * If not expanded, a location code value
820 * starting with Ufcs-, and if that isn't
821 * present it will be added first.
Matt Spinler5fb24c12020-06-04 11:21:33 -0500822 *
Matt Spinler2f9225a2020-08-05 12:58:49 -0500823 * @param[in] node - The node number the location is on. Ignored if the
824 * expanded location code is passed in.
825 *
826 * @param[in] expanded - If the location code already has the relevent
827 * VPD fields embedded in it.
Matt Spinler5fb24c12020-06-04 11:21:33 -0500828 *
Matt Spinlerbad056b2023-01-25 14:16:57 -0600829 * @return std::vector<std::string> - The inventory D-Bus objects
Matt Spinler5fb24c12020-06-04 11:21:33 -0500830 */
Matt Spinlerbad056b2023-01-25 14:16:57 -0600831 std::vector<std::string>
832 getInventoryFromLocCode(const std::string& locationCode, uint16_t node,
833 bool expanded) const override;
Matt Spinler5fb24c12020-06-04 11:21:33 -0500834
Matt Spinler34a904c2020-08-05 14:53:28 -0500835 /**
Matt Spinler34a904c2020-08-05 14:53:28 -0500836 * @brief Sets the Asserted property on the LED group passed in.
837 *
838 * @param[in] ledGroup - The LED group D-Bus path
839 * @param[in] value - The value to set it to
840 */
841 void assertLEDGroup(const std::string& ledGroup, bool value) const override;
842
Matt Spinler993168d2021-04-07 16:05:03 -0500843 /**
844 * @brief Sets the Functional property on the OperationalStatus
845 * interface on a D-Bus object.
846 *
847 * @param[in] objectPath - The D-Bus object path
848 * @param[in] functional - The value
849 */
850 void setFunctional(const std::string& objectPath,
851 bool functional) const override;
852
Sumit Kumar3b8ed7f2021-05-18 12:38:35 -0500853 /**
Sumit Kumar76198a22021-07-15 05:59:57 -0500854 * @brief Sets the critical association on the D-Bus object.
855 *
856 * @param[in] objectPath - The D-Bus object path
857 */
858 void setCriticalAssociation(const std::string& objectPath) const override;
859
860 /**
Sumit Kumar3b8ed7f2021-05-18 12:38:35 -0500861 * @brief Returns the manufacturing QuiesceOnError property
862 *
863 * @return bool - Manufacturing QuiesceOnError property
864 */
865 bool getQuiesceOnError() const override;
866
Sumit Kumar9d43a722021-08-24 09:46:19 -0500867 /**
868 * @brief Returns the dump status
869 *
870 * @param[in] type - The dump type to check for
871 *
872 * @return bool dump status
873 */
874 std::vector<bool>
875 checkDumpStatus(const std::vector<std::string>& type) const override;
876
Jayanth Othayothecaa2fc2021-11-05 02:02:52 -0500877 /**
878 * @brief Create guard record
879 *
880 * @param[in] binPath: phal devtree binary path used as key
881 * @param[in] type: Guard type
882 * @param[in] logPath: error log entry object path
883 */
884 void createGuardRecord(const std::vector<uint8_t>& binPath,
885 const std::string& type,
886 const std::string& logPath) const override;
887
Sumit Kumar3e274432021-09-14 06:37:56 -0500888 /**
889 * @brief Create Progress SRC property on the boot progress
890 * interface on a D-Bus object.
891 *
892 * @param[in] priSRC - Primary SRC value
893 * @param[in] srcStruct - Full SRC base structure
894 */
895 void
896 createProgressSRC(const uint64_t& priSRC,
897 const std::vector<uint8_t>& srcStruct) const override;
898
Sumit Kumar027bf282022-01-24 11:25:19 -0600899 /**
900 * @brief Get the list of unresolved OpenBMC event log ids that have an
901 * associated hardware isolation entry.
902 *
903 * @return std::vector<uint32_t> - The list of log ids
904 */
905 std::vector<uint32_t> getLogIDWithHwIsolation() const override;
906
Vijay Lobo875b6c72021-10-20 17:38:56 -0500907 /**
908 * @brief Returns the latest raw progress SRC from the State.Boot.Raw
909 * D-Bus interface.
910 *
911 * @return std::vector<uint8_t>: The progress SRC bytes
912 */
913 std::vector<uint8_t> getRawProgressSRC() const override;
914
Arya K Padmand8ae6182024-07-19 06:25:10 -0500915 /**
916 * @brief Returns the FRUs DI property value hosted on the VINI iterface for
917 * the given location code.
918 *
919 * @param[in] locationCode - The location code of the FRU
920 *
921 * @return std::optional<std::vector<uint8_t>> - The FRUs DI or
922 * std::nullopt
923 */
924 std::optional<std::vector<uint8_t>>
925 getDIProperty(const std::string& locationCode) const override;
926
harsh-agarwal1d763db32024-09-03 09:18:50 -0500927 /**
928 * @brief Finds all D-Bus Associated paths that contain any of the
929 * interfaces passed in, by using GetAssociatedSubTreePaths.
930 *
931 * @param[in] associatedPath - The D-Bus object path
932 * @param[in] subtree - The subtree path for which the result should be
933 * fetched
934 * @param[in] depth - The maximum subtree depth for which results should be
935 * fetched
936 * @param[in] interfaces - The desired interfaces
937 *
938 * @return The D-Bus paths.
939 */
940 DBusPathList getAssociatedPaths(
941 const DBusPath& associatedPath, const DBusPath& subtree, int32_t depth,
942 const DBusInterfaceList& interfaces) const override;
943
Matt Spinler2a28c932020-02-03 14:23:40 -0600944 private:
945 /**
946 * @brief Reads the BMC firmware version string and puts it into
947 * _bmcFWVersion.
948 */
949 void readBMCFWVersion();
Matt Spinlera7d9d962019-11-06 15:01:25 -0600950
951 /**
Matt Spinler2a28c932020-02-03 14:23:40 -0600952 * @brief Reads the server firmware version string and puts it into
953 * _serverFWVersion.
Matt Spinlerc8705e22019-09-11 12:36:07 -0500954 */
Matt Spinler2a28c932020-02-03 14:23:40 -0600955 void readServerFWVersion();
Matt Spinlerc8705e22019-09-11 12:36:07 -0500956
957 /**
Matt Spinler2a28c932020-02-03 14:23:40 -0600958 * @brief Reads the BMC firmware version ID and puts it into
959 * _bmcFWVersionID.
Matt Spinlera7d9d962019-11-06 15:01:25 -0600960 */
Matt Spinler2a28c932020-02-03 14:23:40 -0600961 void readBMCFWVersionID();
Matt Spinlera7d9d962019-11-06 15:01:25 -0600962
963 /**
Matt Spinlerb3d488f2020-02-21 15:30:46 -0600964 * @brief Finds all D-Bus paths that contain any of the interfaces
965 * passed in, by using GetSubTreePaths.
966 *
967 * @param[in] interfaces - The desired interfaces
968 *
969 * @return The D-Bus paths.
970 */
971 DBusPathList getPaths(const DBusInterfaceList& interfaces) const;
972
973 /**
974 * @brief The interfacesAdded callback used on the inventory to
975 * find the D-Bus object that has the motherboard interface.
976 * When the motherboard is found, it then adds a PropertyWatcher
977 * for the motherboard CCIN.
978 */
Patrick Williams45e83522022-07-22 19:26:52 -0500979 void motherboardIfaceAdded(sdbusplus::message_t& msg);
Matt Spinlerb3d488f2020-02-21 15:30:46 -0600980
981 /**
Matt Spinler5b423652023-05-04 13:08:44 -0500982 * @brief Start watching for the hotpluggable FRUs to become
983 * present.
984 */
985 void startFruPlugWatch();
986
987 /**
988 * @brief Create a D-Bus match object for the Present property
989 * to change on the path passed in.
990 * @param[in] path - The path to watch.
991 */
992 void addHotplugWatch(const std::string& path);
993
994 /**
995 * @brief Callback when an inventory interface was added.
996 *
997 * Only does something if it's one of the hotpluggable FRUs,
998 * in which case it will treat it as a hotplug if the
999 * Present property is true.
1000 *
1001 * @param[in] msg - The InterfacesAdded signal contents.
1002 */
1003 void inventoryIfaceAdded(sdbusplus::message_t& msg);
1004
1005 /**
1006 * @brief Callback when the Present property changes.
1007 *
1008 * If present, will run the registered callbacks.
1009 *
1010 * @param[in] msg - The PropertiesChanged signal contents.
1011 */
1012 void presenceChanged(sdbusplus::message_t& msg);
1013
1014 /**
1015 * @brief If the Present property is in the properties map
1016 * passed in and it is true, notify the subscribers.
1017 *
1018 * @param[in] path - The object path of the inventory item.
1019 * @param[in] properties - The properties map
1020 */
1021 void notifyPresenceSubsribers(const std::string& path,
1022 const DBusPropertyMap& properties);
1023
1024 /**
Matt Spinler0e4d72e2020-08-05 12:36:53 -05001025 * @brief Adds the Ufcs- prefix to the location code passed in
1026 * if necessary.
Matt Spinler5fb24c12020-06-04 11:21:33 -05001027 *
Matt Spinler0e4d72e2020-08-05 12:36:53 -05001028 * Needed because the location codes that come back from the
Matt Spinler5fb24c12020-06-04 11:21:33 -05001029 * message registry and device callout JSON don't have it.
1030 *
1031 * @param[in] - The location code without a prefix, like P1-C1
1032 *
1033 * @return std::string - The location code with the prefix
1034 */
1035 static std::string addLocationCodePrefix(const std::string& locationCode);
1036
Arya K Padmanafba3162024-08-30 07:41:32 -05001037 /**
1038 * @brief A helper API to check whether the PHAL device tree is exists,
1039 * ensuring the PHAL init API can be invoked.
1040 *
1041 * @return true if the PHAL device tree is exists, otherwise false
1042 */
1043 bool isPHALDevTreeExist() const;
1044
Arya K Padman0b758fb2024-09-06 11:59:45 -05001045#ifdef PEL_ENABLE_PHAL
Arya K Padmanafba3162024-08-30 07:41:32 -05001046 /**
1047 * @brief A helper API to init PHAL libraries
1048 *
1049 * @return None
1050 */
1051 void initPHAL();
Arya K Padman0b758fb2024-09-06 11:59:45 -05001052#endif // PEL_ENABLE_PHAL
Arya K Padmanafba3162024-08-30 07:41:32 -05001053
1054 /**
1055 * @brief A helper API to subscribe to systemd signals
1056 *
1057 * @return None
1058 */
1059 void subscribeToSystemdSignals();
1060
1061 /**
1062 * @brief A helper API to unsubscribe to systemd signals
1063 *
1064 * @return None
1065 */
1066 void unsubscribeFromSystemdSignals();
Arya K Padmanafba3162024-08-30 07:41:32 -05001067
Matt Spinler5fb24c12020-06-04 11:21:33 -05001068 /**
Matt Spinler2a28c932020-02-03 14:23:40 -06001069 * @brief The D-Bus property or interface watchers that have callbacks
1070 * registered that will set members in this class when
1071 * they change.
Matt Spinlerc8705e22019-09-11 12:36:07 -05001072 */
Matt Spinler2a28c932020-02-03 14:23:40 -06001073 std::vector<std::unique_ptr<DBusWatcher>> _properties;
Matt Spinlera7d9d962019-11-06 15:01:25 -06001074
Matt Spinler5b423652023-05-04 13:08:44 -05001075 std::unique_ptr<sdbusplus::bus::match_t> _invIaMatch;
1076
1077 /**
1078 * @brief The matches for watching for hotplugs.
1079 *
1080 * A map so we can check that we never get duplicates.
1081 */
1082 std::map<std::string, std::unique_ptr<sdbusplus::bus::match_t>>
1083 _invPresentMatches;
1084
Matt Spinlera7d9d962019-11-06 15:01:25 -06001085 /**
Matt Spinlerc8705e22019-09-11 12:36:07 -05001086 * @brief The sdbusplus bus object for making D-Bus calls.
1087 */
Patrick Williams45e83522022-07-22 19:26:52 -05001088 sdbusplus::bus_t& _bus;
Arya K Padmanafba3162024-08-30 07:41:32 -05001089
Arya K Padmanafba3162024-08-30 07:41:32 -05001090 /**
1091 * @brief Watcher to check "openpower-update-bios-attr-table" service
1092 * is "done" to init PHAL libraires
1093 */
1094 std::unique_ptr<sdbusplus::bus::match_t> _systemdMatch;
Arya K Padmanafba3162024-08-30 07:41:32 -05001095
1096 /**
1097 * @brief A slot object for async dbus call
1098 */
1099 sdbusplus::slot_t _systemdSlot;
Matt Spinlerc8705e22019-09-11 12:36:07 -05001100};
1101
1102} // namespace pels
1103} // namespace openpower