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 */ AnyOf(const Fan & fan,const std::vector<std::reference_wrapper<PresenceSensor>> & s)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 */ isPowerOn() const108 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