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