blob: f59f6f57ec94ac973bd3f81b646b68759024c224 [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>
Matt Spinlere824f982017-05-11 10:07:55 -05006#include "event.hpp"
Matt Spinlera9406a72017-04-27 14:29:24 -05007#include "timer.hpp"
Matt Spinlerabf8da32017-04-27 14:08:45 -05008
9namespace phosphor
10{
11namespace fan
12{
13namespace monitor
14{
15
16class Fan;
17
Matt Spinler78689dd2017-09-28 10:12:07 -050018constexpr auto FAN_SENSOR_PATH = "/xyz/openbmc_project/sensors/fan_tach/";
Matt Spinlerabf8da32017-04-27 14:08:45 -050019
20/**
Matthew Barth0a9fe162018-01-26 12:53:15 -060021 * The mode fan monitor will run in:
22 * - init - only do the initialization steps
23 * - monitor - run normal monitoring algorithm
24 */
25enum class Mode
26{
27 init,
28 monitor
29};
30
31/**
Matthew Barth3800ae72018-02-19 16:08:04 -060032 * The mode that the timer is running in:
33 * - func - Transition to functional state timer
34 * - nonfunc - Transition to nonfunctional state timer
35 */
36enum class TimerMode
37{
38 func,
39 nonfunc
40};
41
42/**
Matt Spinlerabf8da32017-04-27 14:08:45 -050043 * @class TachSensor
44 *
45 * This class represents the sensor that reads a tach value.
46 * It may also support a Target, which is the property used to
47 * set a speed. Since it doesn't necessarily have a Target, it
48 * won't for sure know if it is running too slow, so it leaves
49 * that determination to other code.
50 *
51 * This class has a parent Fan object that knows about all
52 * sensors for that fan.
53 */
54class TachSensor
55{
56 public:
57
58 TachSensor() = delete;
59 TachSensor(const TachSensor&) = delete;
Brad Bishopfa0766e2017-07-30 15:42:10 -040060 // TachSensor is not moveable since the this pointer is used as systemd
61 // callback context.
62 TachSensor(TachSensor&&) = delete;
Matt Spinlerabf8da32017-04-27 14:08:45 -050063 TachSensor& operator=(const TachSensor&) = delete;
Brad Bishopfa0766e2017-07-30 15:42:10 -040064 TachSensor& operator=(TachSensor&&) = delete;
Matt Spinlerabf8da32017-04-27 14:08:45 -050065 ~TachSensor() = default;
66
67 /**
68 * @brief Constructor
69 *
Matthew Barth0a9fe162018-01-26 12:53:15 -060070 * @param[in] mode - mode of fan monitor
Matt Spinlerabf8da32017-04-27 14:08:45 -050071 * @param[in] bus - the dbus object
72 * @param[in] fan - the parent fan object
73 * @param[in] id - the id of the sensor
74 * @param[in] hasTarget - if the sensor supports
75 * setting the speed
Matthew Barth9396bcc2018-02-19 14:13:20 -060076 * @param[in] funcDelay - Delay to mark functional
Lei YU80f271b2018-01-31 15:24:46 +080077 * @param[in] interface - the interface of the target
Lei YU8e5d1972018-01-26 17:14:00 +080078 * @param[in] factor - the factor of the sensor target
79 * @param[in] offset - the offset of the sensor target
Matt Spinlerabf8da32017-04-27 14:08:45 -050080 * @param[in] timeout - Normal timeout value to use
Matt Spinlera9406a72017-04-27 14:29:24 -050081 * @param[in] events - sd_event pointer
Matt Spinlerabf8da32017-04-27 14:08:45 -050082 */
Matthew Barth0a9fe162018-01-26 12:53:15 -060083 TachSensor(Mode mode,
84 sdbusplus::bus::bus& bus,
Matt Spinlerabf8da32017-04-27 14:08:45 -050085 Fan& fan,
86 const std::string& id,
87 bool hasTarget,
Matthew Barth9396bcc2018-02-19 14:13:20 -060088 size_t funcDelay,
Lei YU80f271b2018-01-31 15:24:46 +080089 const std::string& interface,
Lei YU8e5d1972018-01-26 17:14:00 +080090 size_t factor,
91 size_t offset,
Matt Spinlera9406a72017-04-27 14:29:24 -050092 size_t timeout,
Matt Spinlere824f982017-05-11 10:07:55 -050093 phosphor::fan::event::EventPtr& events);
Matt Spinlerabf8da32017-04-27 14:08:45 -050094
95 /**
96 * @brief Returns the target speed value
97 */
Matthew Barthf552ea52018-01-15 16:22:04 -060098 uint64_t getTarget() const;
Matt Spinlerabf8da32017-04-27 14:08:45 -050099
100 /**
101 * @brief Returns the input speed value
102 */
103 inline int64_t getInput() const
104 {
105 return _tachInput;
106 }
107
108 /**
109 * @brief Returns true if sensor has a target
110 */
111 inline bool hasTarget() const
112 {
113 return _hasTarget;
114 }
115
116 /**
Lei YU80f271b2018-01-31 15:24:46 +0800117 * @brief Returns the interface of the sensor target
118 */
119 inline std::string getInterface() const
120 {
121 return _interface;
122 }
123
124 /**
Lei YU8e5d1972018-01-26 17:14:00 +0800125 * @brief Returns the factor of the sensor target
126 */
127 inline size_t getFactor() const
128 {
129 return _factor;
130 }
131
132 /**
133 * @brief Returns the offset of the sensor target
134 */
135 inline size_t getOffset() const
136 {
137 return _offset;
138 }
139
140 /**
Matt Spinlerabf8da32017-04-27 14:08:45 -0500141 * Returns true if the hardware behind this
142 * sensor is considered working OK/functional.
143 */
144 inline bool functional() const
145 {
146 return _functional;
147 }
148
149 /**
Matthew Barthd199dcd2017-11-20 10:36:41 -0600150 * Set the functional status and update inventory to match
Matt Spinlerabf8da32017-04-27 14:08:45 -0500151 */
Matthew Barthd199dcd2017-11-20 10:36:41 -0600152 void setFunctional(bool functional);
Matt Spinlerabf8da32017-04-27 14:08:45 -0500153
Matt Spinlera9406a72017-04-27 14:29:24 -0500154 /**
Matt Spinler6fa181c2017-09-27 16:24:45 -0500155 * @brief Says if the timer is running or not
156 *
157 * @return bool - if timer is currently running
Matt Spinlera9406a72017-04-27 14:29:24 -0500158 */
Matt Spinler6fa181c2017-09-27 16:24:45 -0500159 inline bool timerRunning()
Matt Spinlera9406a72017-04-27 14:29:24 -0500160 {
Matt Spinler6fa181c2017-09-27 16:24:45 -0500161 return _timer.running();
162 }
163
164 /**
Matthew Barth3800ae72018-02-19 16:08:04 -0600165 * @brief Stops the timer when the given mode differs and starts
166 * the associated timer for the mode given if not already running
167 *
168 * @param[in] mode - mode of timer to start
Matt Spinler6fa181c2017-09-27 16:24:45 -0500169 */
Matthew Barth3800ae72018-02-19 16:08:04 -0600170 void startTimer(TimerMode mode);
Matt Spinler6fa181c2017-09-27 16:24:45 -0500171
172 /**
173 * @brief Stops the timer
174 */
175 inline void stopTimer()
176 {
177 _timer.stop();
Matt Spinlera9406a72017-04-27 14:29:24 -0500178 }
179
180 /**
Matthew Barth3800ae72018-02-19 16:08:04 -0600181 * @brief Return the given timer mode's delay time
182 *
183 * @param[in] mode - mode of timer to get delay time for
Matt Spinlera9406a72017-04-27 14:29:24 -0500184 */
Matthew Barth3800ae72018-02-19 16:08:04 -0600185 std::chrono::microseconds getDelay(TimerMode mode);
Matt Spinlera9406a72017-04-27 14:29:24 -0500186
Matt Spinlerce75b512017-07-26 15:10:48 -0500187 /**
188 * Returns the sensor name
189 */
190 inline const std::string& name() const
191 {
192 return _name;
193 };
194
Matt Spinlerabf8da32017-04-27 14:08:45 -0500195 private:
196
197 /**
Matt Spinlerebaae612017-04-27 14:21:48 -0500198 * @brief Returns the match string to use for matching
199 * on a properties changed signal.
200 */
201 std::string getMatchString(const std::string& interface);
202
203 /**
Matt Spinlerebaae612017-04-27 14:21:48 -0500204 * @brief Reads the Target property and stores in _tachTarget.
205 * Also calls Fan::tachChanged().
206 *
207 * @param[in] msg - the dbus message
Matt Spinlerebaae612017-04-27 14:21:48 -0500208 */
Brad Bishop771659f2017-07-30 19:52:21 -0400209 void handleTargetChange(sdbusplus::message::message& msg);
Matt Spinlerebaae612017-04-27 14:21:48 -0500210
211 /**
212 * @brief Reads the Value property and stores in _tachInput.
213 * Also calls Fan::tachChanged().
214 *
215 * @param[in] msg - the dbus message
Matt Spinlerebaae612017-04-27 14:21:48 -0500216 */
Brad Bishop771659f2017-07-30 19:52:21 -0400217 void handleTachChange(sdbusplus::message::message& msg);
Matt Spinlerebaae612017-04-27 14:21:48 -0500218
Matthew Barth4d982852017-11-17 09:37:13 -0600219 /**
220 * @brief Updates the Functional property in the inventory
221 * for this tach sensor based on the value passed in.
222 *
223 * @param[in] functional - If the Functional property should
224 * be set to true or false.
225 */
226 void updateInventory(bool functional);
Matt Spinlerebaae612017-04-27 14:21:48 -0500227
228 /**
Matt Spinlerabf8da32017-04-27 14:08:45 -0500229 * @brief the dbus object
230 */
231 sdbusplus::bus::bus& _bus;
232
233 /**
234 * @brief Reference to the parent Fan object
235 */
236 Fan& _fan;
237
238 /**
239 * @brief The name of the sensor, including the full path
240 *
241 * For example /xyz/openbmc_project/sensors/fan_tach/fan0
242 */
243 const std::string _name;
244
245 /**
Matthew Barth4d982852017-11-17 09:37:13 -0600246 * @brief The inventory name of the sensor, including the full path
247 */
248 const std::string _invName;
249
250 /**
Matt Spinlerabf8da32017-04-27 14:08:45 -0500251 * @brief If functional (not too slow). The parent
252 * fan object sets this.
253 */
Matthew Barthd199dcd2017-11-20 10:36:41 -0600254 bool _functional;
Matt Spinlerabf8da32017-04-27 14:08:45 -0500255
256 /**
257 * @brief If the sensor has a Target property (can set speed)
258 */
259 const bool _hasTarget;
260
261 /**
Matthew Barth9396bcc2018-02-19 14:13:20 -0600262 * @brief Amount of time to delay updating to functional
263 */
264 const size_t _funcDelay;
265
266 /**
Lei YU80f271b2018-01-31 15:24:46 +0800267 * @brief The interface that the target implements
268 */
269 const std::string _interface;
270
271 /**
Lei YU8e5d1972018-01-26 17:14:00 +0800272 * @brief The factor of target to get fan rpm
273 */
274 const size_t _factor;
275
276 /**
277 * @brief The offset of target to get fan rpm
278 */
279 const size_t _offset;
280
281 /**
Matt Spinlerabf8da32017-04-27 14:08:45 -0500282 * @brief The input speed, from the Value dbus property
283 */
284 int64_t _tachInput = 0;
285
286 /**
287 * @brief The current target speed, from the Target dbus property
288 * (if applicable)
289 */
290 uint64_t _tachTarget = 0;
291
292 /**
293 * @brief The timeout value to use
294 */
295 const size_t _timeout;
Matt Spinlerebaae612017-04-27 14:21:48 -0500296
297 /**
Matthew Barth3800ae72018-02-19 16:08:04 -0600298 * @brief Mode that current timer is in
299 */
300 TimerMode _timerMode;
301
302 /**
Matt Spinlera9406a72017-04-27 14:29:24 -0500303 * The timer object
304 */
305 phosphor::fan::util::Timer _timer;
306
307 /**
Matt Spinlerebaae612017-04-27 14:21:48 -0500308 * @brief The match object for the Value properties changed signal
309 */
310 std::unique_ptr<sdbusplus::server::match::match> tachSignal;
311
312 /**
313 * @brief The match object for the Target properties changed signal
314 */
315 std::unique_ptr<sdbusplus::server::match::match> targetSignal;
Matt Spinlerabf8da32017-04-27 14:08:45 -0500316};
317
318}
319}
320}