xref: /openbmc/dbus-sensors/src/Thresholds.hpp (revision 77141acb)
1 #pragma once
2 
3 #include "Utils.hpp"
4 
5 #include <boost/asio/io_context.hpp>
6 #include <boost/asio/steady_timer.hpp>
7 #include <nlohmann/json.hpp>
8 
9 #include <list>
10 #include <memory>
11 #include <string>
12 #include <utility>
13 #include <vector>
14 
15 struct Sensor;
16 namespace thresholds
17 {
18 enum class Level
19 {
20     WARNING,
21     CRITICAL,
22     PERFORMANCELOSS,
23     SOFTSHUTDOWN,
24     HARDSHUTDOWN,
25     ERROR
26 };
27 enum class Direction
28 {
29     HIGH,
30     LOW,
31     ERROR
32 };
33 struct Threshold
34 {
35     Threshold(
36         const Level& lev, const Direction& dir, const double& val,
37         const double hysteresis = std::numeric_limits<double>::quiet_NaN(),
38         bool write = true) :
39         level(lev),
40         direction(dir), value(val), hysteresis(hysteresis), writeable(write)
41     {}
42     Level level;
43     Direction direction;
44     double value;
45     double hysteresis;
46     bool writeable;
47 
48     bool operator==(const Threshold& rhs) const
49     {
50         return (level == rhs.level && direction == rhs.direction &&
51                 value == rhs.value);
52     }
53 };
54 
55 void assertThresholds(Sensor* sensor, double assertValue,
56                       thresholds::Level level, thresholds::Direction direction,
57                       bool assert);
58 
59 struct TimerUsed
60 {
61     bool used;
62     Level level;
63     Direction direction;
64     bool assert;
65 };
66 
67 using TimerPair = std::pair<struct TimerUsed, boost::asio::steady_timer>;
68 
69 struct ThresholdTimer
70 {
71 
72     explicit ThresholdTimer(boost::asio::io_context& ioService) : io(ioService)
73     {}
74 
75     bool hasActiveTimer(const Threshold& threshold, bool assert)
76     {
77         for (TimerPair& timer : timers)
78         {
79             if (timer.first.used)
80             {
81                 if ((timer.first.level == threshold.level) &&
82                     (timer.first.direction == threshold.direction) &&
83                     (timer.first.assert == assert))
84                 {
85                     return true;
86                 }
87             }
88         }
89         return false;
90     }
91 
92     void stopTimer(const Threshold& threshold, bool assert)
93     {
94         struct TimerUsed timerUsed = {};
95         for (TimerPair& timer : timers)
96         {
97             timerUsed = timer.first;
98             if (timerUsed.used)
99             {
100                 if ((timerUsed.level == threshold.level) &&
101                     (timerUsed.direction == threshold.direction) &&
102                     (timerUsed.assert == assert))
103                 {
104                     timer.second.cancel();
105                 }
106             }
107         }
108     }
109 
110     void startTimer(const std::weak_ptr<Sensor>& weakSensor,
111                     const Threshold& threshold, bool assert,
112                     double assertValue);
113 
114     boost::asio::io_context& io;
115     std::list<TimerPair> timers;
116 };
117 
118 bool parseThresholdsFromConfig(
119     const SensorData& sensorData,
120     std::vector<thresholds::Threshold>& thresholdVector,
121     const std::string* matchLabel = nullptr, const int* sensorIndex = nullptr);
122 
123 bool parseThresholdsFromAttr(
124     std::vector<thresholds::Threshold>& thresholdVector,
125     const std::string& inputPath, const double& scaleFactor,
126     const double& offset = 0);
127 
128 struct ThresholdDefinition
129 {
130     Level level;
131     uint8_t sevOrder;
132     const char* levelName;
133 };
134 
135 constexpr static std::array<thresholds::ThresholdDefinition, 5> thresProp = {
136     {{Level::WARNING, 0, "Warning"},
137      {Level::CRITICAL, 1, "Critical"},
138      {Level::PERFORMANCELOSS, 2, "PerformanceLoss"},
139      {Level::SOFTSHUTDOWN, 3, "SoftShutdown"},
140      {Level::HARDSHUTDOWN, 4, "HardShutdown"}}};
141 
142 std::string getInterface(Level level);
143 
144 void persistThreshold(const std::string& path, const std::string& baseInterface,
145                       const thresholds::Threshold& threshold,
146                       std::shared_ptr<sdbusplus::asio::connection>& conn,
147                       size_t thresholdCount, const std::string& label);
148 
149 void updateThresholds(Sensor* sensor);
150 // returns false if a critical threshold has been crossed, true otherwise
151 bool checkThresholds(Sensor* sensor);
152 void checkThresholdsPowerDelay(const std::weak_ptr<Sensor>& weakSensor,
153                                ThresholdTimer& thresholdTimer);
154 
155 } // namespace thresholds
156