1 #pragma once
2 
3 #include "fan.hpp"
4 #include "power_state.hpp"
5 #include "rpolicy.hpp"
6 
7 #include <sdeventplus/utility/timer.hpp>
8 
9 #include <functional>
10 #include <vector>
11 
12 namespace phosphor
13 {
14 namespace fan
15 {
16 namespace presence
17 {
18 
19 class PresenceSensor;
20 
21 /**
22  * @class AnyOf
23  * @brief AnyOf redundancy policy.
24  *
25  * The any of redundancy policy monitors all sensor
26  * states in the redundancy set and reports true when any
27  * sensor in the set reports true.
28  */
29 class AnyOf : public RedundancyPolicy
30 {
31   public:
32     AnyOf() = delete;
33     AnyOf(const AnyOf&) = default;
34     AnyOf& operator=(const AnyOf&) = default;
35     AnyOf(AnyOf&&) = default;
36     AnyOf& operator=(AnyOf&&) = default;
37     ~AnyOf() = default;
38 
39     /**
40      * @brief Construct an any of bitwise policy.
41      *
42      * @param[in] fan - The fan associated with the policy.
43      * @param[in] s - The set of sensors associated with the policy.
44      * @param[in] e - EEPROM device instance
45      */
46     AnyOf(const Fan& fan,
47           const std::vector<std::reference_wrapper<PresenceSensor>>& s,
48           std::unique_ptr<EEPROMDevice> e);
49 
50     /**
51      * @brief Construct an any of bitwise policy.
52      *
53      * @param[in] fan - The fan associated with the policy.
54      * @param[in] s - The set of sensors associated with the policy.
55      */
56     AnyOf(const Fan& fan,
57           const std::vector<std::reference_wrapper<PresenceSensor>>& s) :
58         AnyOf(fan, s, nullptr)
59     {}
60 
61     /**
62      * @brief stateChanged
63      *
64      * Update the inventory and execute the fallback
65      * policy.
66      *
67      * @param[in] present - The new presence state according
68      *             to the specified sensor.
69      * @param[in] sensor - The sensor reporting the new state.
70      */
71     void stateChanged(bool present, PresenceSensor& sensor) override;
72 
73     /**
74      * @brief monitor
75      *
76      * Start monitoring the fan.
77      */
78     void monitor() override;
79 
80   private:
81     /**
82      * @brief Checks that the sensors contained in this policy all
83      *        agree on the presence value.  If they don't, then call
84      *        logConflict() on the sensors that don't think the fan
85      *        is present as they may be broken.
86      *
87      * This check will only happen when power is on.
88      */
89     void checkSensorConflicts();
90 
91     /**
92      * @brief Callback function called after a post-poweron delay.
93      *
94      * The _powerOnDelayTimer is started when _powerState says the
95      * power is on to give fans a bit of time to spin up so tachs
96      * wouldn't be zero.  This is the callback function for that timer.
97      *
98      * It will call checkSensorConflicts().
99      */
100     void delayedAfterPowerOn();
101 
102     /**
103      * @brief Says if power is on, though not until the post
104      *        power on delay is complete.
105      *
106      * @return bool - if power is on.
107      */
108     inline bool isPowerOn() const
109     {
110         return _powerOn;
111     }
112 
113     /**
114      * @brief Called by the PowerState object when the power
115      *        state changes.
116      *
117      * When power changes to on:
118      *   - Clears the memory of previous sensor conflicts.
119      *   - Starts the post power on delay timer.
120      *
121      * @param[in] powerOn - If power is now on or off.
122      */
123     void powerStateChanged(bool powerOn);
124 
125     static constexpr size_t sensorPos = 0;
126     static constexpr size_t presentPos = 1;
127     static constexpr size_t conflictPos = 2;
128 
129     /**
130      * @brief All presence sensors in the redundancy set.
131      *
132      * Each entry contains:
133      *  - A reference to a PresenceSensor
134      *  - The current presence state
135      *  - If the sensors have logged conflicts in their answers.
136      */
137     std::vector<std::tuple<std::reference_wrapper<PresenceSensor>, bool, bool>>
138         state;
139 
140     /**
141      * @brief Pointer to the PowerState object used to track power changes.
142      */
143     std::shared_ptr<PowerState> _powerState;
144 
145     /**
146      * @brief Post power on delay timer, where the conflict checking code
147      *        doesn't consider power on until this timer expires.
148      *
149      * This gives fans a chance to start spinning before checking them.
150      */
151     sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>
152         _powerOnDelayTimer;
153 
154     /**
155      * @brief Current power state.
156      */
157     bool _powerOn;
158 };
159 
160 } // namespace presence
161 } // namespace fan
162 } // namespace phosphor
163