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