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