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