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 */ 45 AnyOf(const Fan& fan, 46 const std::vector<std::reference_wrapper<PresenceSensor>>& s); 47 48 /** 49 * @brief stateChanged 50 * 51 * Update the inventory and execute the fallback 52 * policy. 53 * 54 * @param[in] present - The new presence state according 55 * to the specified sensor. 56 * @param[in] sensor - The sensor reporting the new state. 57 */ 58 void stateChanged(bool present, PresenceSensor& sensor) override; 59 60 /** 61 * @brief monitor 62 * 63 * Start monitoring the fan. 64 */ 65 void monitor() override; 66 67 private: 68 /** 69 * @brief Checks that the sensors contained in this policy all 70 * agree on the presence value. If they don't, then call 71 * logConflict() on the sensors that don't think the fan 72 * is present as they may be broken. 73 * 74 * This check will only happen when power is on. 75 */ 76 void checkSensorConflicts(); 77 78 /** 79 * @brief Callback function called after a post-poweron delay. 80 * 81 * The _powerOnDelayTimer is started when _powerState says the 82 * power is on to give fans a bit of time to spin up so tachs 83 * wouldn't be zero. This is the callback function for that timer. 84 * 85 * It will call checkSensorConflicts(). 86 */ 87 void delayedAfterPowerOn(); 88 89 /** 90 * @brief Says if power is on, though not until the post 91 * power on delay is complete. 92 * 93 * @return bool - if power is on. 94 */ 95 inline bool isPowerOn() const 96 { 97 return _powerOn; 98 } 99 100 /** 101 * @brief Called by the PowerState object when the power 102 * state changes. 103 * 104 * When power changes to on: 105 * - Clears the memory of previous sensor conflicts. 106 * - Starts the post power on delay timer. 107 * 108 * @param[in] powerOn - If power is now on or off. 109 */ 110 void powerStateChanged(bool powerOn); 111 112 static constexpr size_t sensorPos = 0; 113 static constexpr size_t presentPos = 1; 114 static constexpr size_t conflictPos = 2; 115 116 /** 117 * @brief All presence sensors in the redundancy set. 118 * 119 * Each entry contains: 120 * - A reference to a PresenceSensor 121 * - The current presence state 122 * - If the sensors have logged conflicts in their answers. 123 */ 124 std::vector<std::tuple<std::reference_wrapper<PresenceSensor>, bool, bool>> 125 state; 126 127 /** 128 * @brief Pointer to the PowerState object used to track power changes. 129 */ 130 std::shared_ptr<PowerState> _powerState; 131 132 /** 133 * @brief Post power on delay timer, where the conflict checking code 134 * doesn't consider power on until this timer expires. 135 * 136 * This gives fans a chance to start spinning before checking them. 137 */ 138 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> 139 _powerOnDelayTimer; 140 141 /** 142 * @brief Current power state. 143 */ 144 bool _powerOn; 145 }; 146 147 } // namespace presence 148 } // namespace fan 149 } // namespace phosphor 150