blob: 2a643c5c6e12b7179b5689f5ecace62f66e1cc78 [file] [log] [blame]
Matt Spinlerabf8da32017-04-27 14:08:45 -05001#pragma once
2
3#include <chrono>
4#include <sdbusplus/bus.hpp>
5#include <sdbusplus/server.hpp>
William A. Kennington III8fd879f2018-10-30 19:49:29 -07006#include <sdeventplus/clock.hpp>
William A. Kennington III1cfc2f12018-10-19 17:29:46 -07007#include <sdeventplus/event.hpp>
William A. Kennington III8fd879f2018-10-30 19:49:29 -07008#include <sdeventplus/utility/timer.hpp>
Matt Spinlerabf8da32017-04-27 14:08:45 -05009
10namespace phosphor
11{
12namespace fan
13{
14namespace monitor
15{
16
17class Fan;
18
Matt Spinler78689dd2017-09-28 10:12:07 -050019constexpr auto FAN_SENSOR_PATH = "/xyz/openbmc_project/sensors/fan_tach/";
Matt Spinlerabf8da32017-04-27 14:08:45 -050020
21/**
Matthew Barth0a9fe162018-01-26 12:53:15 -060022 * The mode fan monitor will run in:
23 * - init - only do the initialization steps
24 * - monitor - run normal monitoring algorithm
25 */
26enum class Mode
27{
28 init,
29 monitor
30};
31
32/**
Matthew Barth3800ae72018-02-19 16:08:04 -060033 * The mode that the timer is running in:
34 * - func - Transition to functional state timer
35 * - nonfunc - Transition to nonfunctional state timer
36 */
37enum class TimerMode
38{
39 func,
40 nonfunc
41};
42
43/**
Matt Spinlerabf8da32017-04-27 14:08:45 -050044 * @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 */
55class TachSensor
56{
57 public:
58
59 TachSensor() = delete;
60 TachSensor(const TachSensor&) = delete;
Brad Bishopfa0766e2017-07-30 15:42:10 -040061 // TachSensor is not moveable since the this pointer is used as systemd
62 // callback context.
63 TachSensor(TachSensor&&) = delete;
Matt Spinlerabf8da32017-04-27 14:08:45 -050064 TachSensor& operator=(const TachSensor&) = delete;
Brad Bishopfa0766e2017-07-30 15:42:10 -040065 TachSensor& operator=(TachSensor&&) = delete;
Matt Spinlerabf8da32017-04-27 14:08:45 -050066 ~TachSensor() = default;
67
68 /**
69 * @brief Constructor
70 *
Matthew Barth0a9fe162018-01-26 12:53:15 -060071 * @param[in] mode - mode of fan monitor
Matt Spinlerabf8da32017-04-27 14:08:45 -050072 * @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
Matthew Barth9396bcc2018-02-19 14:13:20 -060077 * @param[in] funcDelay - Delay to mark functional
Lei YU80f271b2018-01-31 15:24:46 +080078 * @param[in] interface - the interface of the target
Lei YU8e5d1972018-01-26 17:14:00 +080079 * @param[in] factor - the factor of the sensor target
80 * @param[in] offset - the offset of the sensor target
Matt Spinlerabf8da32017-04-27 14:08:45 -050081 * @param[in] timeout - Normal timeout value to use
William A. Kennington III1cfc2f12018-10-19 17:29:46 -070082 * @param[in] event - Event loop reference
Matt Spinlerabf8da32017-04-27 14:08:45 -050083 */
Matthew Barth0a9fe162018-01-26 12:53:15 -060084 TachSensor(Mode mode,
85 sdbusplus::bus::bus& bus,
Matt Spinlerabf8da32017-04-27 14:08:45 -050086 Fan& fan,
87 const std::string& id,
88 bool hasTarget,
Matthew Barth9396bcc2018-02-19 14:13:20 -060089 size_t funcDelay,
Lei YU80f271b2018-01-31 15:24:46 +080090 const std::string& interface,
Lei YU8e5d1972018-01-26 17:14:00 +080091 size_t factor,
92 size_t offset,
Matt Spinlera9406a72017-04-27 14:29:24 -050093 size_t timeout,
William A. Kennington III1cfc2f12018-10-19 17:29:46 -070094 const sdeventplus::Event& event);
Matt Spinlerabf8da32017-04-27 14:08:45 -050095
96 /**
97 * @brief Returns the target speed value
98 */
Matthew Barthf552ea52018-01-15 16:22:04 -060099 uint64_t getTarget() const;
Matt Spinlerabf8da32017-04-27 14:08:45 -0500100
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 /**
Lei YU80f271b2018-01-31 15:24:46 +0800118 * @brief Returns the interface of the sensor target
119 */
120 inline std::string getInterface() const
121 {
122 return _interface;
123 }
124
125 /**
Lei YU8e5d1972018-01-26 17:14:00 +0800126 * @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 /**
Matt Spinlerabf8da32017-04-27 14:08:45 -0500142 * 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 /**
Matthew Barthd199dcd2017-11-20 10:36:41 -0600151 * Set the functional status and update inventory to match
Matt Spinlerabf8da32017-04-27 14:08:45 -0500152 */
Matthew Barthd199dcd2017-11-20 10:36:41 -0600153 void setFunctional(bool functional);
Matt Spinlerabf8da32017-04-27 14:08:45 -0500154
Matt Spinlera9406a72017-04-27 14:29:24 -0500155 /**
Matt Spinler6fa181c2017-09-27 16:24:45 -0500156 * @brief Says if the timer is running or not
157 *
158 * @return bool - if timer is currently running
Matt Spinlera9406a72017-04-27 14:29:24 -0500159 */
Matt Spinler6fa181c2017-09-27 16:24:45 -0500160 inline bool timerRunning()
Matt Spinlera9406a72017-04-27 14:29:24 -0500161 {
William A. Kennington III8fd879f2018-10-30 19:49:29 -0700162 return _timer.isEnabled();
Matt Spinler6fa181c2017-09-27 16:24:45 -0500163 }
164
165 /**
Matthew Barth3800ae72018-02-19 16:08:04 -0600166 * @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
Matt Spinler6fa181c2017-09-27 16:24:45 -0500170 */
Matthew Barth3800ae72018-02-19 16:08:04 -0600171 void startTimer(TimerMode mode);
Matt Spinler6fa181c2017-09-27 16:24:45 -0500172
173 /**
174 * @brief Stops the timer
175 */
176 inline void stopTimer()
177 {
William A. Kennington III8fd879f2018-10-30 19:49:29 -0700178 _timer.setEnabled(false);
Matt Spinlera9406a72017-04-27 14:29:24 -0500179 }
180
181 /**
Matthew Barth3800ae72018-02-19 16:08:04 -0600182 * @brief Return the given timer mode's delay time
183 *
184 * @param[in] mode - mode of timer to get delay time for
Matt Spinlera9406a72017-04-27 14:29:24 -0500185 */
Matthew Barth3800ae72018-02-19 16:08:04 -0600186 std::chrono::microseconds getDelay(TimerMode mode);
Matt Spinlera9406a72017-04-27 14:29:24 -0500187
Matt Spinlerce75b512017-07-26 15:10:48 -0500188 /**
189 * Returns the sensor name
190 */
191 inline const std::string& name() const
192 {
193 return _name;
194 };
195
Matt Spinlerabf8da32017-04-27 14:08:45 -0500196 private:
197
198 /**
Matt Spinlerebaae612017-04-27 14:21:48 -0500199 * @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 /**
Matt Spinlerebaae612017-04-27 14:21:48 -0500205 * @brief Reads the Target property and stores in _tachTarget.
206 * Also calls Fan::tachChanged().
207 *
208 * @param[in] msg - the dbus message
Matt Spinlerebaae612017-04-27 14:21:48 -0500209 */
Brad Bishop771659f2017-07-30 19:52:21 -0400210 void handleTargetChange(sdbusplus::message::message& msg);
Matt Spinlerebaae612017-04-27 14:21:48 -0500211
212 /**
213 * @brief Reads the Value property and stores in _tachInput.
214 * Also calls Fan::tachChanged().
215 *
216 * @param[in] msg - the dbus message
Matt Spinlerebaae612017-04-27 14:21:48 -0500217 */
Brad Bishop771659f2017-07-30 19:52:21 -0400218 void handleTachChange(sdbusplus::message::message& msg);
Matt Spinlerebaae612017-04-27 14:21:48 -0500219
Matthew Barth4d982852017-11-17 09:37:13 -0600220 /**
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);
Matt Spinlerebaae612017-04-27 14:21:48 -0500228
229 /**
Matt Spinlerabf8da32017-04-27 14:08:45 -0500230 * @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 /**
Matthew Barth4d982852017-11-17 09:37:13 -0600247 * @brief The inventory name of the sensor, including the full path
248 */
249 const std::string _invName;
250
251 /**
Matt Spinlerabf8da32017-04-27 14:08:45 -0500252 * @brief If functional (not too slow). The parent
253 * fan object sets this.
254 */
Matthew Barthd199dcd2017-11-20 10:36:41 -0600255 bool _functional;
Matt Spinlerabf8da32017-04-27 14:08:45 -0500256
257 /**
258 * @brief If the sensor has a Target property (can set speed)
259 */
260 const bool _hasTarget;
261
262 /**
Matthew Barth9396bcc2018-02-19 14:13:20 -0600263 * @brief Amount of time to delay updating to functional
264 */
265 const size_t _funcDelay;
266
267 /**
Lei YU80f271b2018-01-31 15:24:46 +0800268 * @brief The interface that the target implements
269 */
270 const std::string _interface;
271
272 /**
Lei YU8e5d1972018-01-26 17:14:00 +0800273 * @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 /**
Matt Spinlerabf8da32017-04-27 14:08:45 -0500283 * @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;
Matt Spinlerebaae612017-04-27 14:21:48 -0500297
298 /**
Matthew Barth3800ae72018-02-19 16:08:04 -0600299 * @brief Mode that current timer is in
300 */
301 TimerMode _timerMode;
302
303 /**
Matt Spinlera9406a72017-04-27 14:29:24 -0500304 * The timer object
305 */
William A. Kennington III8fd879f2018-10-30 19:49:29 -0700306 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> _timer;
Matt Spinlera9406a72017-04-27 14:29:24 -0500307
308 /**
Matt Spinlerebaae612017-04-27 14:21:48 -0500309 * @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;
Matt Spinlerabf8da32017-04-27 14:08:45 -0500317};
318
319}
320}
321}