1 #pragma once
2 
3 #include "dbus_types.hpp"
4 #include "dbus_watcher.hpp"
5 
6 #include <phosphor-logging/lg2.hpp>
7 #include <sdbusplus/bus.hpp>
8 #include <sdbusplus/bus/match.hpp>
9 
10 #include <expected>
11 #include <filesystem>
12 #include <fstream>
13 #include <unordered_map>
14 
15 namespace openpower
16 {
17 namespace pels
18 {
19 
20 /**
21  * @class DataInterface
22  *
23  * A base class for gathering data about the system for use
24  * in PELs. Implemented this way to facilitate mocking.
25  */
26 class 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     /**
37      * @brief Returns the machine Type/Model
38      *
39      * @return string - The machine Type/Model string
40      */
41     virtual std::string getMachineTypeModel() const = 0;
42 
43     /**
44      * @brief Returns the machine serial number
45      *
46      * @return string - The machine serial number
47      */
48     virtual std::string getMachineSerialNumber() const = 0;
49 
50     /**
51      * @brief Says if the system is managed by a hardware
52      *        management console.
53      * @return bool - If the system is HMC managed
54      */
isHMCManaged() const55     virtual bool isHMCManaged() const
56     {
57         return _hmcManaged;
58     }
59 
60     /**
61      * @brief Says if the host is up and running
62      *
63      * @return bool - If the host is running
64      */
isHostUp() const65     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      */
subscribeToHostStateChange(const std::string & name,HostStateChangeFunc func)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      */
unsubscribeFromHostStateChange(const std::string & name)93     void unsubscribeFromHostStateChange(const std::string& name)
94     {
95         _hostChangeCallbacks.erase(name);
96     }
97 
98     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      */
subscribeToFruPresent(const std::string & name,FRUPresentFunc func)111     void subscribeToFruPresent(const std::string& name, FRUPresentFunc func)
112     {
113         _fruPresentCallbacks[name] = std::move(func);
114     }
115 
116     /**
117      * @brief Returns the BMC firmware version
118      *
119      * @return std::string - The BMC version
120      */
getBMCFWVersion() const121     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      */
getServerFWVersion() const131     virtual std::string getServerFWVersion() const
132     {
133         return _serverFWVersion;
134     }
135 
136     /**
137      * @brief Returns the BMC FW version ID
138      *
139      * @return std::string - The BMC FW version ID
140      */
getBMCFWVersionID() const141     virtual std::string getBMCFWVersionID() const
142     {
143         return _bmcFWVersionID;
144     }
145 
146     /**
147      * @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      */
getProcessName(const std::string & pid) const153     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 
168     /**
169      * @brief Returns the time the system was running.
170      *
171      * @return std::optional<uint64_t> - The System uptime or std::nullopt
172      */
getUptimeInSeconds() const173     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      */
getBMCUptime(uint64_t seconds) const201     std::string getBMCUptime(uint64_t seconds) const
202     {
203         time_t t(seconds);
204         tm* p = gmtime(&t);
205 
206         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";
211 
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      */
getBMCLoadAvg() const221     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     /**
254      * @brief Returns the 'send event logs to host' setting.
255      *
256      * @return bool - If sending PELs to the host is enabled.
257      */
getHostPELEnablement() const258     virtual bool getHostPELEnablement() const
259     {
260         return _sendPELsToHost;
261     }
262 
263     /**
264      * @brief Returns the BMC state
265      *
266      * @return std::string - The BMC state property value
267      */
getBMCState() const268     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      */
getChassisState() const278     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      */
getChassisTransition() const289     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      */
getHostState() const299     virtual std::string getHostState() const
300     {
301         return _hostState;
302     }
303 
304     /**
305      * @brief Returns the Boot state
306      *
307      * @return std::string - The Boot state property value
308      */
getBootState() const309     virtual std::string getBootState() const
310     {
311         return _bootState;
312     }
313 
314     /**
315      * @brief Returns the motherboard CCIN
316      *
317      * @return std::string The motherboard CCIN
318      */
319     virtual std::string getMotherboardCCIN() const = 0;
320 
321     /**
322      * @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     /**
329      * @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
333      * @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      */
337     virtual void getHWCalloutFields(
338         const std::string& inventoryPath, std::string& fruPartNumber,
339         std::string& ccin, std::string& serialNumber) const = 0;
340 
341     /**
342      * @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     /**
352      * @brief Get the list of system type names the system is called.
353      *
354      * @return std::vector<std::string> - The list of names
355      */
356     virtual std::vector<std::string> getSystemNames() const = 0;
357 
358     /**
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     /**
374      * @brief Returns the inventory paths for the FRU that the location
375      *        code represents.
376      *
377      * @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.
382      *
383      * @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.
388      *
389      * @return std::vector<std::string> - The inventory D-Bus objects
390      */
391     virtual std::vector<std::string>
392         getInventoryFromLocCode(const std::string& LocationCode, uint16_t node,
393                                 bool expanded) const = 0;
394 
395     /**
396      * @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 
404     /**
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 
414     /**
415      * @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     /**
423      * @brief Returns the manufacturing QuiesceOnError property
424      *
425      * @return bool - Manufacturing QuiesceOnError property
426      */
427     virtual bool getQuiesceOnError() const = 0;
428 
429     /**
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 
446     /**
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 
454     /**
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 
465     /**
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 
476     /**
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 
484     /**
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 
492     /**
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      *
510      * @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.
513      */
514     bool isDIMM(const std::string& locCode);
515 
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 
540   protected:
541     /**
542      * @brief Sets the host on/off state and runs any
543      *        callback functions (if there was a change).
544      */
setHostUp(bool hostUp)545     void setHostUp(bool hostUp)
546     {
547         if (_hostUp != hostUp)
548         {
549             _hostUp = hostUp;
550 
551             for (auto& [name, func] : _hostChangeCallbacks)
552             {
553                 try
554                 {
555                     func(_hostUp);
556                 }
557                 catch (const std::exception& e)
558                 {
559                     lg2::error(
560                         "A host state change callback threw an exception");
561                 }
562             }
563         }
564     }
565 
566     /**
567      * @brief Runs the callback functions registered when
568      *        FRUs become present.
569      */
setFruPresent(const std::string & locationCode)570     void setFruPresent(const std::string& locationCode)
571     {
572         for (const auto& [_, func] : _fruPresentCallbacks)
573         {
574             try
575             {
576                 func(locationCode);
577             }
578             catch (const std::exception& e)
579             {
580                 lg2::error("A FRU present callback threw an exception");
581             }
582         }
583     }
584 
585     /**
586      * @brief The hardware management console status.  Always kept
587      *        up to date.
588      */
589     bool _hmcManaged = false;
590 
591     /**
592      * @brief The host up status.  Always kept up to date.
593      */
594     bool _hostUp = false;
595 
596     /**
597      * @brief The map of host state change subscriber
598      *        names to callback functions.
599      */
600     std::map<std::string, HostStateChangeFunc> _hostChangeCallbacks;
601 
602     /**
603      * @brief The map of FRU present subscriber
604      *        names to callback functions.
605      */
606     std::map<std::string, FRUPresentFunc> _fruPresentCallbacks;
607 
608     /**
609      * @brief The BMC firmware version string
610      */
611     std::string _bmcFWVersion;
612 
613     /**
614      * @brief The server firmware version string
615      */
616     std::string _serverFWVersion;
617 
618     /**
619      * @brief The BMC firmware version ID string
620      */
621     std::string _bmcFWVersionID;
622 
623     /**
624      * @brief If sending PELs is enabled.
625      *
626      * This is usually set to false in manufacturing test.
627      */
628     bool _sendPELsToHost = true;
629 
630     /**
631      * @brief The BMC state property
632      */
633     std::string _bmcState;
634 
635     /**
636      * @brief The Chassis current power state property
637      */
638     std::string _chassisState;
639 
640     /**
641      * @brief The Chassis requested power transition property
642      */
643     std::string _chassisTransition;
644 
645     /**
646      * @brief The host state property
647      */
648     std::string _hostState;
649 
650     /**
651      * @brief The boot state property
652      */
653     std::string _bootState;
654 
655     /**
656      * @brief A cache storage for location code and its FRU Type
657      *  - The key 'std::string' represents the locationCode of the FRU
658      *  - The bool value - true indicates the FRU is a DIMM
659      *                     false indicates the FRU is a non DIMM.
660      */
661     std::unordered_map<std::string, bool> _locationCache;
662 };
663 
664 /**
665  * @class DataInterface
666  *
667  * Concrete implementation of DataInterfaceBase.
668  */
669 class DataInterface : public DataInterfaceBase
670 {
671   public:
672     DataInterface() = delete;
673     ~DataInterface() = default;
674     DataInterface(const DataInterface&) = default;
675     DataInterface& operator=(const DataInterface&) = default;
676     DataInterface(DataInterface&&) = default;
677     DataInterface& operator=(DataInterface&&) = default;
678 
679     /**
680      * @brief Constructor
681      *
682      * @param[in] bus - The sdbusplus bus object
683      */
684     explicit DataInterface(sdbusplus::bus_t& bus);
685 
686     /**
687      * @brief Finds the D-Bus service name that hosts the
688      *        passed in path and interface.
689      *
690      * @param[in] objectPath - The D-Bus object path
691      * @param[in] interface - The D-Bus interface
692      */
693     DBusService getService(const std::string& objectPath,
694                            const std::string& interface) const;
695 
696     /**
697      * @brief Wrapper for the 'GetAll' properties method call
698      *
699      * @param[in] service - The D-Bus service to call it on
700      * @param[in] objectPath - The D-Bus object path
701      * @param[in] interface - The interface to get the props on
702      *
703      * @return DBusPropertyMap - The property results
704      */
705     DBusPropertyMap getAllProperties(const std::string& service,
706                                      const std::string& objectPath,
707                                      const std::string& interface) const;
708     /**
709      * @brief Wrapper for the 'Get' properties method call
710      *
711      * @param[in] service - The D-Bus service to call it on
712      * @param[in] objectPath - The D-Bus object path
713      * @param[in] interface - The interface to get the property on
714      * @param[in] property - The property name
715      * @param[out] value - Filled in with the property value.
716      */
717     void getProperty(const std::string& service, const std::string& objectPath,
718                      const std::string& interface, const std::string& property,
719                      DBusValue& value) const;
720     /**
721      * @brief Returns the machine Type/Model
722      *
723      * @return string - The machine Type/Model string
724      */
725     std::string getMachineTypeModel() const override;
726 
727     /**
728      * @brief Returns the machine serial number
729      *
730      * @return string - The machine serial number
731      */
732     std::string getMachineSerialNumber() const override;
733 
734     /**
735      * @brief Returns the motherboard CCIN
736      *
737      * @return std::string The motherboard CCIN
738      */
739     std::string getMotherboardCCIN() const override;
740 
741     /**
742      * @brief Returns the system IM
743      *
744      * @return std::vector The system IM keyword in 4 byte vector
745      */
746     std::vector<uint8_t> getSystemIMKeyword() const override;
747 
748     /**
749      * @brief Get the fields from the inventory necessary for doing
750      *        a callout on an inventory path.
751      *
752      * @param[in] inventoryPath - The item to get the data for
753      * @param[out] fruPartNumber - Filled in with the VINI/FN keyword
754      * @param[out] ccin - Filled in with the VINI/CC keyword
755      * @param[out] serialNumber - Filled in with the VINI/SN keyword
756      */
757     void getHWCalloutFields(const std::string& inventoryPath,
758                             std::string& fruPartNumber, std::string& ccin,
759                             std::string& serialNumber) const override;
760 
761     /**
762      * @brief Get the location code for an inventory item.
763      *
764      * Throws an exception if the inventory item doesn't have the
765      * location code interface.
766      *
767      * @param[in] inventoryPath - The item to get the data for
768      *
769      * @return std::string - The location code
770      */
771     std::string
772         getLocationCode(const std::string& inventoryPath) const override;
773 
774     /**
775      * @brief Get the list of system type names the system is called.
776      *
777      * @return std::vector<std::string> - The list of names
778      */
779     std::vector<std::string> getSystemNames() const override;
780 
781     /**
782      * @brief Fills in the placeholder 'Ufcs' in the passed in location
783      *        code with the machine feature code and serial number, which
784      *        is needed to create a valid location code.
785      *
786      * @param[in] locationCode - Location code value starting with Ufcs-, and
787      *                           if that isn't present it will be added first.
788      *
789      * @param[in] node - The node number the location is one.
790      *
791      * @return std::string - The expanded location code
792      */
793     std::string expandLocationCode(const std::string& locationCode,
794                                    uint16_t node) const override;
795 
796     /**
797      * @brief Returns the inventory paths for the FRU that the location
798      *        code represents.
799      *
800      * @param[in] locationCode - If an expanded location code, then the
801      *                           full location code.
802      *                           If not expanded, a location code value
803      *                           starting with Ufcs-, and if that isn't
804      *                           present it will be added first.
805      *
806      * @param[in] node - The node number the location is on.  Ignored if the
807      *                   expanded location code is passed in.
808      *
809      * @param[in] expanded - If the location code already has the relevent
810      *                       VPD fields embedded in it.
811      *
812      * @return std::vector<std::string> - The inventory D-Bus objects
813      */
814     std::vector<std::string>
815         getInventoryFromLocCode(const std::string& locationCode, uint16_t node,
816                                 bool expanded) const override;
817 
818     /**
819      * @brief Sets the Asserted property on the LED group passed in.
820      *
821      * @param[in] ledGroup - The LED group D-Bus path
822      * @param[in] value - The value to set it to
823      */
824     void assertLEDGroup(const std::string& ledGroup, bool value) const override;
825 
826     /**
827      * @brief Sets the Functional property on the OperationalStatus
828      *        interface on a D-Bus object.
829      *
830      * @param[in] objectPath - The D-Bus object path
831      * @param[in] functional - The value
832      */
833     void setFunctional(const std::string& objectPath,
834                        bool functional) const override;
835 
836     /**
837      * @brief Sets the critical association on the D-Bus object.
838      *
839      * @param[in] objectPath - The D-Bus object path
840      */
841     void setCriticalAssociation(const std::string& objectPath) const override;
842 
843     /**
844      * @brief Returns the manufacturing QuiesceOnError property
845      *
846      * @return bool - Manufacturing QuiesceOnError property
847      */
848     bool getQuiesceOnError() const override;
849 
850     /**
851      * @brief Returns the dump status
852      *
853      * @param[in] type - The dump type to check for
854      *
855      * @return bool dump status
856      */
857     std::vector<bool>
858         checkDumpStatus(const std::vector<std::string>& type) const override;
859 
860     /**
861      * @brief Create guard record
862      *
863      *  @param[in] binPath: phal devtree binary path used as key
864      *  @param[in] type: Guard type
865      *  @param[in] logPath: error log entry object path
866      */
867     void createGuardRecord(const std::vector<uint8_t>& binPath,
868                            const std::string& type,
869                            const std::string& logPath) const override;
870 
871     /**
872      * @brief Create Progress SRC property on the boot progress
873      *        interface on a D-Bus object.
874      *
875      * @param[in] priSRC - Primary SRC value
876      * @param[in] srcStruct - Full SRC base structure
877      */
878     void
879         createProgressSRC(const uint64_t& priSRC,
880                           const std::vector<uint8_t>& srcStruct) const override;
881 
882     /**
883      * @brief Get the list of unresolved OpenBMC event log ids that have an
884      * associated hardware isolation entry.
885      *
886      * @return std::vector<uint32_t> - The list of log ids
887      */
888     std::vector<uint32_t> getLogIDWithHwIsolation() const override;
889 
890     /**
891      * @brief Returns the latest raw progress SRC from the State.Boot.Raw
892      *        D-Bus interface.
893      *
894      * @return std::vector<uint8_t>: The progress SRC bytes
895      */
896     std::vector<uint8_t> getRawProgressSRC() const override;
897 
898     /**
899      * @brief Returns the FRUs DI property value hosted on the VINI iterface for
900      * the given location code.
901      *
902      * @param[in] locationCode - The location code of the FRU
903      *
904      * @return std::optional<std::vector<uint8_t>> -  The FRUs DI or
905      * std::nullopt
906      */
907     std::optional<std::vector<uint8_t>>
908         getDIProperty(const std::string& locationCode) const override;
909 
910   private:
911     /**
912      * @brief Reads the BMC firmware version string and puts it into
913      *        _bmcFWVersion.
914      */
915     void readBMCFWVersion();
916 
917     /**
918      * @brief Reads the server firmware version string and puts it into
919      *        _serverFWVersion.
920      */
921     void readServerFWVersion();
922 
923     /**
924      * @brief Reads the BMC firmware version ID and puts it into
925      *        _bmcFWVersionID.
926      */
927     void readBMCFWVersionID();
928 
929     /**
930      * @brief Finds all D-Bus paths that contain any of the interfaces
931      *        passed in, by using GetSubTreePaths.
932      *
933      * @param[in] interfaces - The desired interfaces
934      *
935      * @return The D-Bus paths.
936      */
937     DBusPathList getPaths(const DBusInterfaceList& interfaces) const;
938 
939     /**
940      * @brief The interfacesAdded callback used on the inventory to
941      *        find the D-Bus object that has the motherboard interface.
942      *        When the motherboard is found, it then adds a PropertyWatcher
943      *        for the motherboard CCIN.
944      */
945     void motherboardIfaceAdded(sdbusplus::message_t& msg);
946 
947     /**
948      * @brief Start watching for the hotpluggable FRUs to become
949      *        present.
950      */
951     void startFruPlugWatch();
952 
953     /**
954      * @brief Create a D-Bus match object for the Present property
955      *        to change on the path passed in.
956      * @param[in] path - The path to watch.
957      */
958     void addHotplugWatch(const std::string& path);
959 
960     /**
961      * @brief Callback when an inventory interface was added.
962      *
963      * Only does something if it's one of the hotpluggable FRUs,
964      * in which case it will treat it as a hotplug if the
965      * Present property is true.
966      *
967      * @param[in] msg - The InterfacesAdded signal contents.
968      */
969     void inventoryIfaceAdded(sdbusplus::message_t& msg);
970 
971     /**
972      * @brief Callback when the Present property changes.
973      *
974      * If present, will run the registered callbacks.
975      *
976      * @param[in] msg - The PropertiesChanged signal contents.
977      */
978     void presenceChanged(sdbusplus::message_t& msg);
979 
980     /**
981      * @brief If the Present property is in the properties map
982      *        passed in and it is true, notify the subscribers.
983      *
984      * @param[in] path - The object path of the inventory item.
985      * @param[in] properties - The properties map
986      */
987     void notifyPresenceSubsribers(const std::string& path,
988                                   const DBusPropertyMap& properties);
989 
990     /**
991      * @brief Adds the Ufcs- prefix to the location code passed in
992      *        if necessary.
993      *
994      * Needed because the location codes that come back from the
995      * message registry and device callout JSON don't have it.
996      *
997      * @param[in] - The location code without a prefix, like P1-C1
998      *
999      * @return std::string - The location code with the prefix
1000      */
1001     static std::string addLocationCodePrefix(const std::string& locationCode);
1002 
1003     /**
1004      * @brief A helper API to check whether the PHAL device tree is exists,
1005      *        ensuring the PHAL init API can be invoked.
1006      *
1007      * @return true if the PHAL device tree is exists, otherwise false
1008      */
1009     bool isPHALDevTreeExist() const;
1010 
1011 #ifdef PEL_ENABLE_PHAL
1012     /**
1013      * @brief A helper API to init PHAL libraries
1014      *
1015      * @return None
1016      */
1017     void initPHAL();
1018 #endif // PEL_ENABLE_PHAL
1019 
1020     /**
1021      * @brief A helper API to subscribe to systemd signals
1022      *
1023      * @return None
1024      */
1025     void subscribeToSystemdSignals();
1026 
1027     /**
1028      * @brief A helper API to unsubscribe to systemd signals
1029      *
1030      * @return None
1031      */
1032     void unsubscribeFromSystemdSignals();
1033 
1034     /**
1035      * @brief The D-Bus property or interface watchers that have callbacks
1036      *        registered that will set members in this class when
1037      *        they change.
1038      */
1039     std::vector<std::unique_ptr<DBusWatcher>> _properties;
1040 
1041     std::unique_ptr<sdbusplus::bus::match_t> _invIaMatch;
1042 
1043     /**
1044      * @brief The matches for watching for hotplugs.
1045      *
1046      * A map so we can check that we never get duplicates.
1047      */
1048     std::map<std::string, std::unique_ptr<sdbusplus::bus::match_t>>
1049         _invPresentMatches;
1050 
1051     /**
1052      * @brief The sdbusplus bus object for making D-Bus calls.
1053      */
1054     sdbusplus::bus_t& _bus;
1055 
1056     /**
1057      * @brief Watcher to check "openpower-update-bios-attr-table" service
1058      *        is "done" to init PHAL libraires
1059      */
1060     std::unique_ptr<sdbusplus::bus::match_t> _systemdMatch;
1061 
1062     /**
1063      * @brief A slot object for async dbus call
1064      */
1065     sdbusplus::slot_t _systemdSlot;
1066 };
1067 
1068 } // namespace pels
1069 } // namespace openpower
1070