1 #pragma once 2 3 #include <sdbusplus/bus.hpp> 4 #include <sdbusplus/server.hpp> 5 #include <sdeventplus/clock.hpp> 6 #include <sdeventplus/event.hpp> 7 #include <sdeventplus/utility/timer.hpp> 8 9 #include <chrono> 10 11 namespace phosphor 12 { 13 namespace fan 14 { 15 namespace monitor 16 { 17 18 class Fan; 19 20 constexpr auto FAN_SENSOR_PATH = "/xyz/openbmc_project/sensors/fan_tach/"; 21 22 /** 23 * The mode fan monitor will run in: 24 * - init - only do the initialization steps 25 * - monitor - run normal monitoring algorithm 26 */ 27 enum class Mode 28 { 29 init, 30 monitor 31 }; 32 33 /** 34 * The mode that the timer is running in: 35 * - func - Transition to functional state timer 36 * - nonfunc - Transition to nonfunctional state timer 37 */ 38 enum class TimerMode 39 { 40 func, 41 nonfunc 42 }; 43 44 /** 45 * @class TachSensor 46 * 47 * This class represents the sensor that reads a tach value. 48 * It may also support a Target, which is the property used to 49 * set a speed. Since it doesn't necessarily have a Target, it 50 * won't for sure know if it is running too slow, so it leaves 51 * that determination to other code. 52 * 53 * This class has a parent Fan object that knows about all 54 * sensors for that fan. 55 */ 56 class TachSensor 57 { 58 public: 59 TachSensor() = delete; 60 TachSensor(const TachSensor&) = delete; 61 // TachSensor is not moveable since the this pointer is used as systemd 62 // callback context. 63 TachSensor(TachSensor&&) = delete; 64 TachSensor& operator=(const TachSensor&) = delete; 65 TachSensor& operator=(TachSensor&&) = delete; 66 ~TachSensor() = default; 67 68 /** 69 * @brief Constructor 70 * 71 * @param[in] mode - mode of fan monitor 72 * @param[in] bus - the dbus object 73 * @param[in] fan - the parent fan object 74 * @param[in] id - the id of the sensor 75 * @param[in] hasTarget - if the sensor supports 76 * setting the speed 77 * @param[in] funcDelay - Delay to mark functional 78 * @param[in] interface - the interface of the target 79 * @param[in] factor - the factor of the sensor target 80 * @param[in] offset - the offset of the sensor target 81 * @param[in] timeout - Normal timeout value to use 82 * @param[in] event - Event loop reference 83 */ 84 TachSensor(Mode mode, sdbusplus::bus::bus& bus, Fan& fan, 85 const std::string& id, bool hasTarget, size_t funcDelay, 86 const std::string& interface, double factor, int64_t offset, 87 size_t timeout, const sdeventplus::Event& event); 88 89 /** 90 * @brief Returns the target speed value 91 */ 92 uint64_t getTarget() const; 93 94 /** 95 * @brief Returns the input speed value 96 */ 97 inline double getInput() const 98 { 99 return _tachInput; 100 } 101 102 /** 103 * @brief Returns true if sensor has a target 104 */ 105 inline bool hasTarget() const 106 { 107 return _hasTarget; 108 } 109 110 /** 111 * @brief Returns the interface of the sensor target 112 */ 113 inline std::string getInterface() const 114 { 115 return _interface; 116 } 117 118 /** 119 * @brief Returns the factor of the sensor target 120 */ 121 inline double getFactor() const 122 { 123 return _factor; 124 } 125 126 /** 127 * @brief Returns the offset of the sensor target 128 */ 129 inline int64_t getOffset() const 130 { 131 return _offset; 132 } 133 134 /** 135 * Returns true if the hardware behind this 136 * sensor is considered working OK/functional. 137 */ 138 inline bool functional() const 139 { 140 return _functional; 141 } 142 143 /** 144 * Set the functional status and update inventory to match 145 */ 146 void setFunctional(bool functional); 147 148 /** 149 * @brief Says if the timer is running or not 150 * 151 * @return bool - if timer is currently running 152 */ 153 inline bool timerRunning() 154 { 155 return _timer.isEnabled(); 156 } 157 158 /** 159 * @brief Stops the timer when the given mode differs and starts 160 * the associated timer for the mode given if not already running 161 * 162 * @param[in] mode - mode of timer to start 163 */ 164 void startTimer(TimerMode mode); 165 166 /** 167 * @brief Stops the timer 168 */ 169 inline void stopTimer() 170 { 171 _timer.setEnabled(false); 172 } 173 174 /** 175 * @brief Return the given timer mode's delay time 176 * 177 * @param[in] mode - mode of timer to get delay time for 178 */ 179 std::chrono::microseconds getDelay(TimerMode mode); 180 181 /** 182 * Returns the sensor name 183 */ 184 inline const std::string& name() const 185 { 186 return _name; 187 }; 188 189 private: 190 /** 191 * @brief Returns the match string to use for matching 192 * on a properties changed signal. 193 */ 194 std::string getMatchString(const std::string& interface); 195 196 /** 197 * @brief Reads the Target property and stores in _tachTarget. 198 * Also calls Fan::tachChanged(). 199 * 200 * @param[in] msg - the dbus message 201 */ 202 void handleTargetChange(sdbusplus::message::message& msg); 203 204 /** 205 * @brief Reads the Value property and stores in _tachInput. 206 * Also calls Fan::tachChanged(). 207 * 208 * @param[in] msg - the dbus message 209 */ 210 void handleTachChange(sdbusplus::message::message& msg); 211 212 /** 213 * @brief Updates the Functional property in the inventory 214 * for this tach sensor based on the value passed in. 215 * 216 * @param[in] functional - If the Functional property should 217 * be set to true or false. 218 */ 219 void updateInventory(bool functional); 220 221 /** 222 * @brief the dbus object 223 */ 224 sdbusplus::bus::bus& _bus; 225 226 /** 227 * @brief Reference to the parent Fan object 228 */ 229 Fan& _fan; 230 231 /** 232 * @brief The name of the sensor, including the full path 233 * 234 * For example /xyz/openbmc_project/sensors/fan_tach/fan0 235 */ 236 const std::string _name; 237 238 /** 239 * @brief The inventory name of the sensor, including the full path 240 */ 241 const std::string _invName; 242 243 /** 244 * @brief If functional (not too slow). The parent 245 * fan object sets this. 246 */ 247 bool _functional; 248 249 /** 250 * @brief If the sensor has a Target property (can set speed) 251 */ 252 const bool _hasTarget; 253 254 /** 255 * @brief Amount of time to delay updating to functional 256 */ 257 const size_t _funcDelay; 258 259 /** 260 * @brief The interface that the target implements 261 */ 262 const std::string _interface; 263 264 /** 265 * @brief The factor of target to get fan rpm 266 */ 267 const double _factor; 268 269 /** 270 * @brief The offset of target to get fan rpm 271 */ 272 const int64_t _offset; 273 274 /** 275 * @brief The input speed, from the Value dbus property 276 */ 277 double _tachInput = 0; 278 279 /** 280 * @brief The current target speed, from the Target dbus property 281 * (if applicable) 282 */ 283 uint64_t _tachTarget = 0; 284 285 /** 286 * @brief The timeout value to use 287 */ 288 const size_t _timeout; 289 290 /** 291 * @brief Mode that current timer is in 292 */ 293 TimerMode _timerMode; 294 295 /** 296 * The timer object 297 */ 298 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> _timer; 299 300 /** 301 * @brief The match object for the Value properties changed signal 302 */ 303 std::unique_ptr<sdbusplus::server::match::match> tachSignal; 304 305 /** 306 * @brief The match object for the Target properties changed signal 307 */ 308 std::unique_ptr<sdbusplus::server::match::match> targetSignal; 309 }; 310 311 } // namespace monitor 312 } // namespace fan 313 } // namespace phosphor 314