1 #pragma once 2 3 #include <chrono> 4 #include <sdbusplus/bus.hpp> 5 #include <sdbusplus/server.hpp> 6 #include "timer.hpp" 7 8 namespace phosphor 9 { 10 namespace fan 11 { 12 namespace monitor 13 { 14 15 class Fan; 16 17 18 /** 19 * @class TachSensor 20 * 21 * This class represents the sensor that reads a tach value. 22 * It may also support a Target, which is the property used to 23 * set a speed. Since it doesn't necessarily have a Target, it 24 * won't for sure know if it is running too slow, so it leaves 25 * that determination to other code. 26 * 27 * This class has a parent Fan object that knows about all 28 * sensors for that fan. 29 */ 30 class TachSensor 31 { 32 public: 33 34 TachSensor() = delete; 35 TachSensor(const TachSensor&) = delete; 36 TachSensor(TachSensor&&) = default; 37 TachSensor& operator=(const TachSensor&) = delete; 38 TachSensor& operator=(TachSensor&&) = default; 39 ~TachSensor() = default; 40 41 /** 42 * @brief Constructor 43 * 44 * @param[in] bus - the dbus object 45 * @param[in] fan - the parent fan object 46 * @param[in] id - the id of the sensor 47 * @param[in] hasTarget - if the sensor supports 48 * setting the speed 49 * @param[in] timeout - Normal timeout value to use 50 * @param[in] events - sd_event pointer 51 */ 52 TachSensor(sdbusplus::bus::bus& bus, 53 Fan& fan, 54 const std::string& id, 55 bool hasTarget, 56 size_t timeout, 57 std::shared_ptr<sd_event>& events); 58 59 /** 60 * @brief Returns the target speed value 61 */ 62 inline uint64_t getTarget() const 63 { 64 return _tachTarget; 65 } 66 67 /** 68 * @brief Returns the input speed value 69 */ 70 inline int64_t getInput() const 71 { 72 return _tachInput; 73 } 74 75 /** 76 * @brief Returns true if sensor has a target 77 */ 78 inline bool hasTarget() const 79 { 80 return _hasTarget; 81 } 82 83 /** 84 * Returns true if the hardware behind this 85 * sensor is considered working OK/functional. 86 */ 87 inline bool functional() const 88 { 89 return _functional; 90 } 91 92 /** 93 * Sets functional status 94 */ 95 inline void setFunctional(bool functional) 96 { 97 _functional = functional; 98 } 99 100 /** 101 * Returns the timer object for this sensor 102 */ 103 inline phosphor::fan::util::Timer& getTimer() 104 { 105 return _timer; 106 } 107 108 /** 109 * @brief Returns the timeout value to use for the sensor 110 */ 111 std::chrono::microseconds getTimeout(); 112 113 private: 114 115 /** 116 * @brief Returns the service name for reading the sensor 117 */ 118 std::string getService(); 119 120 /** 121 * @brief Returns the match string to use for matching 122 * on a properties changed signal. 123 */ 124 std::string getMatchString(const std::string& interface); 125 126 /** 127 * @brief Callback function for a tach input properties 128 * changed signal 129 * 130 * @param[in] msg - the dbus message 131 * @param[in] data - user data 132 * @param[in] err - dbus error 133 */ 134 static int handleTachChangeSignal(sd_bus_message* msg, 135 void* data, 136 sd_bus_error* err); 137 138 /** 139 * @brief Callback function for a Target properties 140 * changed signal 141 * 142 * @param[in] msg - the dbus message 143 * @param[in] data - user data 144 * @param[in] err - dbus error 145 */ 146 static int handleTargetChangeSignal(sd_bus_message* msg, 147 void* data, 148 sd_bus_error* err); 149 150 /** 151 * @brief Reads the Target property and stores in _tachTarget. 152 * Also calls Fan::tachChanged(). 153 * 154 * @param[in] msg - the dbus message 155 * @param[in] err - dbus error 156 */ 157 void handleTargetChange(sdbusplus::message::message& msg, 158 sd_bus_error* err); 159 160 /** 161 * @brief Reads the Value property and stores in _tachInput. 162 * Also calls Fan::tachChanged(). 163 * 164 * @param[in] msg - the dbus message 165 * @param[in] err - dbus error 166 */ 167 void handleTachChange(sdbusplus::message::message& msg, 168 sd_bus_error* err); 169 170 171 /** 172 * @brief the dbus object 173 */ 174 sdbusplus::bus::bus& _bus; 175 176 /** 177 * @brief Reference to the parent Fan object 178 */ 179 Fan& _fan; 180 181 /** 182 * @brief The name of the sensor, including the full path 183 * 184 * For example /xyz/openbmc_project/sensors/fan_tach/fan0 185 */ 186 const std::string _name; 187 188 /** 189 * @brief If functional (not too slow). The parent 190 * fan object sets this. 191 */ 192 bool _functional = true; 193 194 /** 195 * @brief If the sensor has a Target property (can set speed) 196 */ 197 const bool _hasTarget; 198 199 /** 200 * @brief The input speed, from the Value dbus property 201 */ 202 int64_t _tachInput = 0; 203 204 /** 205 * @brief The current target speed, from the Target dbus property 206 * (if applicable) 207 */ 208 uint64_t _tachTarget = 0; 209 210 /** 211 * @brief The timeout value to use 212 */ 213 const size_t _timeout; 214 215 /** 216 * The timer object 217 */ 218 phosphor::fan::util::Timer _timer; 219 220 /** 221 * @brief The match object for the Value properties changed signal 222 */ 223 std::unique_ptr<sdbusplus::server::match::match> tachSignal; 224 225 /** 226 * @brief The match object for the Target properties changed signal 227 */ 228 std::unique_ptr<sdbusplus::server::match::match> targetSignal; 229 }; 230 231 } 232 } 233 } 234