blob: 17c26494ac19cba7360a036a0579cdd59005e61e [file] [log] [blame]
James Feist6714a252018-09-10 15:26:18 -07001#pragma once
Andrew Jefferye73bd0a2023-01-25 10:39:57 +10302
3#include "Utils.hpp"
4
Ed Tanous1f978632023-02-28 18:16:39 -08005#include <boost/asio/io_context.hpp>
Ed Tanous9b4a20e2022-09-06 08:47:11 -07006#include <boost/asio/steady_timer.hpp>
Ed Tanous18b61862025-01-30 10:56:28 -08007#include <sdbusplus/asio/connection.hpp>
James Feist38fb5982020-05-28 10:09:54 -07008
Ed Tanous18b61862025-01-30 10:56:28 -08009#include <array>
10#include <cstddef>
11#include <cstdint>
12#include <limits>
Patrick Venturefd6ba732019-10-31 14:27:39 -070013#include <list>
14#include <memory>
Patrick Venturefd6ba732019-10-31 14:27:39 -070015#include <string>
16#include <utility>
17#include <vector>
James Feist6714a252018-09-10 15:26:18 -070018
James Feist251c7822018-09-12 12:54:15 -070019struct Sensor;
James Feist6714a252018-09-10 15:26:18 -070020namespace thresholds
21{
Jayashree Dhanapal45f27022021-12-07 12:56:35 +053022enum class Level
James Feist6714a252018-09-10 15:26:18 -070023{
24 WARNING,
Jayashree Dhanapal45f27022021-12-07 12:56:35 +053025 CRITICAL,
Rashmica Gupta8d0fd3c2021-11-30 16:07:14 +110026 PERFORMANCELOSS,
Jayashree Dhanapal091c92c2022-01-11 14:55:20 +053027 SOFTSHUTDOWN,
28 HARDSHUTDOWN,
Jayashree Dhanapal45f27022021-12-07 12:56:35 +053029 ERROR
James Feist6714a252018-09-10 15:26:18 -070030};
Jayashree Dhanapal45f27022021-12-07 12:56:35 +053031enum class Direction
James Feist6714a252018-09-10 15:26:18 -070032{
33 HIGH,
Jayashree Dhanapal45f27022021-12-07 12:56:35 +053034 LOW,
35 ERROR
James Feist6714a252018-09-10 15:26:18 -070036};
37struct Threshold
38{
Rashmica Gupta1e34cec2021-08-31 16:47:39 +100039 Threshold(
40 const Level& lev, const Direction& dir, const double& val,
41 const double hysteresis = std::numeric_limits<double>::quiet_NaN(),
42 bool write = true) :
Patrick Williams2aaf7172024-08-16 15:20:40 -040043 level(lev), direction(dir), value(val), hysteresis(hysteresis),
44 writeable(write)
James Feist38fb5982020-05-28 10:09:54 -070045 {}
James Feist6714a252018-09-10 15:26:18 -070046 Level level;
47 Direction direction;
48 double value;
Rashmica Gupta1e34cec2021-08-31 16:47:39 +100049 double hysteresis;
James Feist6714a252018-09-10 15:26:18 -070050 bool writeable;
Jae Hyun Yoo95b8a2d2019-02-25 20:15:09 -080051
52 bool operator==(const Threshold& rhs) const
53 {
54 return (level == rhs.level && direction == rhs.direction &&
55 value == rhs.value);
56 }
James Feist6714a252018-09-10 15:26:18 -070057};
58
Zhikui Ren59b8b9e2020-06-26 18:34:22 -070059void assertThresholds(Sensor* sensor, double assertValue,
60 thresholds::Level level, thresholds::Direction direction,
61 bool assert);
James Feist46342ec2019-03-06 14:03:41 -080062
Yong Li10306bd2020-04-21 16:08:28 +080063struct TimerUsed
64{
65 bool used;
66 Level level;
67 Direction direction;
Zhikui Renbf7cbc82020-07-02 08:44:00 -070068 bool assert;
Yong Li10306bd2020-04-21 16:08:28 +080069};
70
Ed Tanous9b4a20e2022-09-06 08:47:11 -070071using TimerPair = std::pair<struct TimerUsed, boost::asio::steady_timer>;
James Feist43d32fe2019-09-04 10:35:20 -070072
James Feist46342ec2019-03-06 14:03:41 -080073struct ThresholdTimer
74{
Ed Tanous1f978632023-02-28 18:16:39 -080075 explicit ThresholdTimer(boost::asio::io_context& ioService) : io(ioService)
James Feist38fb5982020-05-28 10:09:54 -070076 {}
James Feist46342ec2019-03-06 14:03:41 -080077
Zhikui Renbf7cbc82020-07-02 08:44:00 -070078 bool hasActiveTimer(const Threshold& threshold, bool assert)
79 {
80 for (TimerPair& timer : timers)
81 {
82 if (timer.first.used)
83 {
84 if ((timer.first.level == threshold.level) &&
85 (timer.first.direction == threshold.direction) &&
86 (timer.first.assert == assert))
87 {
88 return true;
89 }
90 }
91 }
92 return false;
93 }
94
95 void stopTimer(const Threshold& threshold, bool assert)
Yong Li10306bd2020-04-21 16:08:28 +080096 {
97 struct TimerUsed timerUsed = {};
98 for (TimerPair& timer : timers)
99 {
100 timerUsed = timer.first;
101 if (timerUsed.used)
102 {
103 if ((timerUsed.level == threshold.level) &&
Zhikui Renbf7cbc82020-07-02 08:44:00 -0700104 (timerUsed.direction == threshold.direction) &&
105 (timerUsed.assert == assert))
Yong Li10306bd2020-04-21 16:08:28 +0800106 {
107 timer.second.cancel();
108 }
109 }
110 }
111 }
112
Zhikui Ren12c2c0e2021-04-28 17:21:21 -0700113 void startTimer(const std::weak_ptr<Sensor>& weakSensor,
114 const Threshold& threshold, bool assert,
Jeff Lind9cd7042020-11-20 15:49:28 +0800115 double assertValue);
James Feist46342ec2019-03-06 14:03:41 -0800116
Ed Tanous1f978632023-02-28 18:16:39 -0800117 boost::asio::io_context& io;
James Feist43d32fe2019-09-04 10:35:20 -0700118 std::list<TimerPair> timers;
James Feist46342ec2019-03-06 14:03:41 -0800119};
120
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700121bool parseThresholdsFromConfig(
James Feistd8705872019-02-08 13:26:09 -0800122 const SensorData& sensorData,
123 std::vector<thresholds::Threshold>& thresholdVector,
Matt Spinler5636d522021-03-17 14:52:18 -0500124 const std::string* matchLabel = nullptr, const int* sensorIndex = nullptr);
James Feist6714a252018-09-10 15:26:18 -0700125
Chris Sidesa3279232023-04-24 16:08:13 -0500126// Sensors touched by parseThresholdFromAttr() are forcibly updated with given
127// parameters, so callers are encouraged to specify a sane hysteresis value for
128// their HW. For reference, the hysteresis fomula used in Sensor.hpp is:
129// hysteresis.trigger = (max_val - min_val) * 0.01
Ed Tanous2049bd22022-07-09 07:20:26 -0700130bool parseThresholdsFromAttr(
131 std::vector<thresholds::Threshold>& thresholdVector,
132 const std::string& inputPath, const double& scaleFactor,
Chris Sidesa3279232023-04-24 16:08:13 -0500133 const double& offset = 0,
134 const double& hysteresis = std::numeric_limits<double>::quiet_NaN());
James Feist251c7822018-09-12 12:54:15 -0700135
Ed Tanousc8fed202022-01-12 14:24:45 -0800136struct ThresholdDefinition
137{
138 Level level;
139 uint8_t sevOrder;
140 const char* levelName;
141};
142
Rashmica Gupta8d0fd3c2021-11-30 16:07:14 +1100143constexpr static std::array<thresholds::ThresholdDefinition, 5> thresProp = {
Ed Tanousc8fed202022-01-12 14:24:45 -0800144 {{Level::WARNING, 0, "Warning"},
145 {Level::CRITICAL, 1, "Critical"},
Rashmica Gupta8d0fd3c2021-11-30 16:07:14 +1100146 {Level::PERFORMANCELOSS, 2, "PerformanceLoss"},
147 {Level::SOFTSHUTDOWN, 3, "SoftShutdown"},
148 {Level::HARDSHUTDOWN, 4, "HardShutdown"}}};
Ed Tanousc8fed202022-01-12 14:24:45 -0800149
Ed Tanous2049bd22022-07-09 07:20:26 -0700150std::string getInterface(Level level);
James Feist6714a252018-09-10 15:26:18 -0700151
Ed Tanous2049bd22022-07-09 07:20:26 -0700152void persistThreshold(const std::string& path, const std::string& baseInterface,
James Feistd8705872019-02-08 13:26:09 -0800153 const thresholds::Threshold& threshold,
James Feista222ba72019-03-01 15:57:51 -0800154 std::shared_ptr<sdbusplus::asio::connection>& conn,
Cheng C Yang6b1247a2020-03-09 23:48:39 +0800155 size_t thresholdCount, const std::string& label);
James Feist251c7822018-09-12 12:54:15 -0700156
Jae Hyun Yoo95b8a2d2019-02-25 20:15:09 -0800157void updateThresholds(Sensor* sensor);
James Feistdc6c55f2018-10-31 12:53:20 -0700158// returns false if a critical threshold has been crossed, true otherwise
James Feistd8705872019-02-08 13:26:09 -0800159bool checkThresholds(Sensor* sensor);
Zhikui Ren12c2c0e2021-04-28 17:21:21 -0700160void checkThresholdsPowerDelay(const std::weak_ptr<Sensor>& weakSensor,
161 ThresholdTimer& thresholdTimer);
Cheng C Yang6b1247a2020-03-09 23:48:39 +0800162
James Feist6714a252018-09-10 15:26:18 -0700163} // namespace thresholds