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] factor - the factor of the sensor target 66 * @param[in] offset - the offset of the sensor target 67 * @param[in] timeout - Normal timeout value to use 68 * @param[in] events - sd_event pointer 69 */ 70 TachSensor(Mode mode, 71 sdbusplus::bus::bus& bus, 72 Fan& fan, 73 const std::string& id, 74 bool hasTarget, 75 size_t factor, 76 size_t offset, 77 size_t timeout, 78 phosphor::fan::event::EventPtr& events); 79 80 /** 81 * @brief Returns the target speed value 82 */ 83 uint64_t getTarget() const; 84 85 /** 86 * @brief Returns the input speed value 87 */ 88 inline int64_t getInput() const 89 { 90 return _tachInput; 91 } 92 93 /** 94 * @brief Returns true if sensor has a target 95 */ 96 inline bool hasTarget() const 97 { 98 return _hasTarget; 99 } 100 101 /** 102 * @brief Returns the factor of the sensor target 103 */ 104 inline size_t getFactor() const 105 { 106 return _factor; 107 } 108 109 /** 110 * @brief Returns the offset of the sensor target 111 */ 112 inline size_t getOffset() const 113 { 114 return _offset; 115 } 116 117 /** 118 * Returns true if the hardware behind this 119 * sensor is considered working OK/functional. 120 */ 121 inline bool functional() const 122 { 123 return _functional; 124 } 125 126 /** 127 * Set the functional status and update inventory to match 128 */ 129 void setFunctional(bool functional); 130 131 /** 132 * @brief Says if the timer is running or not 133 * 134 * @return bool - if timer is currently running 135 */ 136 inline bool timerRunning() 137 { 138 return _timer.running(); 139 } 140 141 /** 142 * @brief Starts the timer for the amount of time 143 * specified in the constructor 144 */ 145 inline void startTimer() 146 { 147 _timer.start( 148 getTimeout(), 149 phosphor::fan::util::Timer::TimerType::oneshot); 150 } 151 152 /** 153 * @brief Stops the timer 154 */ 155 inline void stopTimer() 156 { 157 _timer.stop(); 158 } 159 160 /** 161 * @brief Returns the timeout value to use for the sensor 162 */ 163 std::chrono::microseconds getTimeout(); 164 165 /** 166 * Returns the sensor name 167 */ 168 inline const std::string& name() const 169 { 170 return _name; 171 }; 172 173 private: 174 175 /** 176 * @brief Returns the match string to use for matching 177 * on a properties changed signal. 178 */ 179 std::string getMatchString(const std::string& interface); 180 181 /** 182 * @brief Reads the Target property and stores in _tachTarget. 183 * Also calls Fan::tachChanged(). 184 * 185 * @param[in] msg - the dbus message 186 */ 187 void handleTargetChange(sdbusplus::message::message& msg); 188 189 /** 190 * @brief Reads the Value property and stores in _tachInput. 191 * Also calls Fan::tachChanged(). 192 * 193 * @param[in] msg - the dbus message 194 */ 195 void handleTachChange(sdbusplus::message::message& msg); 196 197 /** 198 * @brief Updates the Functional property in the inventory 199 * for this tach sensor based on the value passed in. 200 * 201 * @param[in] functional - If the Functional property should 202 * be set to true or false. 203 */ 204 void updateInventory(bool functional); 205 206 /** 207 * @brief the dbus object 208 */ 209 sdbusplus::bus::bus& _bus; 210 211 /** 212 * @brief Reference to the parent Fan object 213 */ 214 Fan& _fan; 215 216 /** 217 * @brief The name of the sensor, including the full path 218 * 219 * For example /xyz/openbmc_project/sensors/fan_tach/fan0 220 */ 221 const std::string _name; 222 223 /** 224 * @brief The inventory name of the sensor, including the full path 225 */ 226 const std::string _invName; 227 228 /** 229 * @brief If functional (not too slow). The parent 230 * fan object sets this. 231 */ 232 bool _functional; 233 234 /** 235 * @brief If the sensor has a Target property (can set speed) 236 */ 237 const bool _hasTarget; 238 239 /** 240 * @brief The factor of target to get fan rpm 241 */ 242 const size_t _factor; 243 244 /** 245 * @brief The offset of target to get fan rpm 246 */ 247 const size_t _offset; 248 249 /** 250 * @brief The input speed, from the Value dbus property 251 */ 252 int64_t _tachInput = 0; 253 254 /** 255 * @brief The current target speed, from the Target dbus property 256 * (if applicable) 257 */ 258 uint64_t _tachTarget = 0; 259 260 /** 261 * @brief The timeout value to use 262 */ 263 const size_t _timeout; 264 265 /** 266 * The timer object 267 */ 268 phosphor::fan::util::Timer _timer; 269 270 /** 271 * @brief The match object for the Value properties changed signal 272 */ 273 std::unique_ptr<sdbusplus::server::match::match> tachSignal; 274 275 /** 276 * @brief The match object for the Target properties changed signal 277 */ 278 std::unique_ptr<sdbusplus::server::match::match> targetSignal; 279 }; 280 281 } 282 } 283 } 284