1 #pragma once
2 
3 #include "fan.hpp"
4 #include "power_state.hpp"
5 
6 #include <nlohmann/json.hpp>
7 #include <sdbusplus/bus.hpp>
8 #include <sdbusplus/bus/match.hpp>
9 #include <sdeventplus/clock.hpp>
10 #include <sdeventplus/utility/timer.hpp>
11 
12 namespace phosphor::fan::presence
13 {
14 class PresenceSensor;
15 
16 /**
17  * @class ErrorReporter
18  *
19  * This class will create event logs for missing fans.  The logs are
20  * created after a fan has been missing for an amount of time
21  * specified in the JSON config file while power is on.
22  *
23  * The timers to create event logs are not started when power is off.
24  * When power is turned on, the timers for any missing fans will be
25  * be started.  If any timers are running when power is turned off,
26  * they will be stopped.
27  */
28 class ErrorReporter
29 {
30   public:
31     ErrorReporter() = delete;
32     ~ErrorReporter() = default;
33     ErrorReporter(const ErrorReporter&) = delete;
34     ErrorReporter& operator=(const ErrorReporter&) = delete;
35     ErrorReporter(ErrorReporter&&) = delete;
36     ErrorReporter& operator=(ErrorReporter&&) = delete;
37 
38     /**
39      * @brief Constructor
40      *
41      * @param[in] bus - The sdbusplus bus object
42      * @param[in] fans - The fans for this configuration
43      */
44     ErrorReporter(
45         sdbusplus::bus_t& bus,
46         const std::vector<
47             std::tuple<Fan, std::vector<std::unique_ptr<PresenceSensor>>>>&
48             fans);
49 
50   private:
51     /**
52      * @brief The propertiesChanged callback for the interface that
53      *        contains the Present property of a fan.
54      *
55      * Will start the timer to create an event log if power is on.
56      *
57      * @param[in] msg - The payload of the propertiesChanged signal
58      */
59     void presenceChanged(sdbusplus::message_t& msg);
60 
61     /**
62      * @brief The callback function called by the PowerState class
63      *        when the power state changes.
64      *
65      * Will start timers for missing fans if power is on, and stop
66      * them when power changes to off.
67      *
68      * @param[in] powerState - The new power state
69      */
70     void powerStateChanged(bool powerState);
71 
72     /**
73      * @brief Called when the fan missing timer expires to create
74      *        an event log for a missing fan.
75      *
76      * @param[in] fanPath - The D-Bus path of the missing fan.
77      */
78     void fanMissingTimerExpired(const std::string& fanPath);
79 
80     /**
81      * @brief Checks if the fan missing timer for a fan needs to
82      *        either be started or stopped based on the power and
83      *        presence states.
84      *
85      * @param[in] fanPath - The D-Bus path of the fan
86      */
87     void checkFan(const std::string& fanPath);
88 
89     /**
90      * @brief Reference to the D-Bus connection object.
91      */
92     sdbusplus::bus_t& _bus;
93 
94     /**
95      * @brief The connection to the event loop for the timer.
96      */
97     sdeventplus::Event _event;
98 
99     /**
100      * @brief The propertiesChanged match objects.
101      */
102     std::vector<sdbusplus::bus::match_t> _matches;
103 
104     /**
105      * @brief Base class pointer to the power state implementation.
106      */
107     std::shared_ptr<PowerState> _powerState;
108 
109     /**
110      * @brief The map of fan paths to their presence states.
111      */
112     std::map<std::string, bool> _fanStates;
113 
114     /**
115      * @brief The map of fan paths to their Timer objects with
116      *        the timer expiration time.
117      */
118     std::map<std::string,
119              std::tuple<std::unique_ptr<sdeventplus::utility::Timer<
120                             sdeventplus::ClockId::Monotonic>>,
121                         std::chrono::seconds>>
122         _fanMissingTimers;
123 };
124 
125 } // namespace phosphor::fan::presence
126