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