blob: ca2b0a0b89bfa2bc2a15e3a5f7f9f0574bd12e01 [file] [log] [blame]
James Feist6714a252018-09-10 15:26:18 -07001#pragma once
Patrick Ventureca44b2f2019-10-31 11:02:26 -07002#include "Utils.hpp"
3
James Feist8086aba2020-08-25 16:00:59 -07004#include <boost/asio/deadline_timer.hpp>
James Feist46342ec2019-03-06 14:03:41 -08005#include <boost/asio/io_service.hpp>
James Feist38fb5982020-05-28 10:09:54 -07006#include <nlohmann/json.hpp>
7
Patrick Venturefd6ba732019-10-31 14:27:39 -07008#include <list>
9#include <memory>
Patrick Venturefd6ba732019-10-31 14:27:39 -070010#include <string>
11#include <utility>
12#include <vector>
James Feist6714a252018-09-10 15:26:18 -070013
James Feist251c7822018-09-12 12:54:15 -070014struct Sensor;
James Feist6714a252018-09-10 15:26:18 -070015namespace thresholds
16{
17enum Level
18{
19 WARNING,
20 CRITICAL
21};
22enum Direction
23{
24 HIGH,
25 LOW
26};
27struct Threshold
28{
James Feistd8705872019-02-08 13:26:09 -080029 Threshold(const Level& lev, const Direction& dir, const double& val,
James Feist6714a252018-09-10 15:26:18 -070030 bool write = true) :
31 level(lev),
32 direction(dir), value(val), writeable(write)
James Feist38fb5982020-05-28 10:09:54 -070033 {}
James Feist6714a252018-09-10 15:26:18 -070034 Level level;
35 Direction direction;
36 double value;
37 bool writeable;
Jae Hyun Yoo95b8a2d2019-02-25 20:15:09 -080038
39 bool operator==(const Threshold& rhs) const
40 {
41 return (level == rhs.level && direction == rhs.direction &&
42 value == rhs.value);
43 }
James Feist6714a252018-09-10 15:26:18 -070044};
45
Zhikui Ren59b8b9e2020-06-26 18:34:22 -070046void assertThresholds(Sensor* sensor, double assertValue,
47 thresholds::Level level, thresholds::Direction direction,
48 bool assert);
James Feist46342ec2019-03-06 14:03:41 -080049
Yong Li10306bd2020-04-21 16:08:28 +080050struct TimerUsed
51{
52 bool used;
53 Level level;
54 Direction direction;
Zhikui Renbf7cbc82020-07-02 08:44:00 -070055 bool assert;
Yong Li10306bd2020-04-21 16:08:28 +080056};
57
58using TimerPair = std::pair<struct TimerUsed, boost::asio::deadline_timer>;
James Feist43d32fe2019-09-04 10:35:20 -070059
James Feist46342ec2019-03-06 14:03:41 -080060struct ThresholdTimer
61{
62
James Feist43d32fe2019-09-04 10:35:20 -070063 ThresholdTimer(boost::asio::io_service& ioService, Sensor* sensor) :
64 io(ioService), sensor(sensor)
James Feist38fb5982020-05-28 10:09:54 -070065 {}
James Feist46342ec2019-03-06 14:03:41 -080066
Zhikui Renbf7cbc82020-07-02 08:44:00 -070067 bool hasActiveTimer(const Threshold& threshold, bool assert)
68 {
69 for (TimerPair& timer : timers)
70 {
71 if (timer.first.used)
72 {
73 if ((timer.first.level == threshold.level) &&
74 (timer.first.direction == threshold.direction) &&
75 (timer.first.assert == assert))
76 {
77 return true;
78 }
79 }
80 }
81 return false;
82 }
83
84 void stopTimer(const Threshold& threshold, bool assert)
Yong Li10306bd2020-04-21 16:08:28 +080085 {
86 struct TimerUsed timerUsed = {};
87 for (TimerPair& timer : timers)
88 {
89 timerUsed = timer.first;
90 if (timerUsed.used)
91 {
92 if ((timerUsed.level == threshold.level) &&
Zhikui Renbf7cbc82020-07-02 08:44:00 -070093 (timerUsed.direction == threshold.direction) &&
94 (timerUsed.assert == assert))
Yong Li10306bd2020-04-21 16:08:28 +080095 {
96 timer.second.cancel();
97 }
98 }
99 }
100 }
101
Zhikui Renbf7cbc82020-07-02 08:44:00 -0700102 void startTimer(const Threshold& threshold, bool assert, double assertValue)
James Feist46342ec2019-03-06 14:03:41 -0800103 {
Yong Li10306bd2020-04-21 16:08:28 +0800104 struct TimerUsed timerUsed = {};
James Feist43d32fe2019-09-04 10:35:20 -0700105 constexpr const size_t waitTime = 5;
106 TimerPair* pair = nullptr;
James Feist46342ec2019-03-06 14:03:41 -0800107
James Feist43d32fe2019-09-04 10:35:20 -0700108 for (TimerPair& timer : timers)
James Feist46342ec2019-03-06 14:03:41 -0800109 {
Yong Li10306bd2020-04-21 16:08:28 +0800110 if (!timer.first.used)
James Feist43d32fe2019-09-04 10:35:20 -0700111 {
112 pair = &timer;
113 break;
114 }
James Feist46342ec2019-03-06 14:03:41 -0800115 }
James Feist43d32fe2019-09-04 10:35:20 -0700116 if (pair == nullptr)
James Feist46342ec2019-03-06 14:03:41 -0800117 {
Yong Li10306bd2020-04-21 16:08:28 +0800118 pair = &timers.emplace_back(timerUsed,
119 boost::asio::deadline_timer(io));
James Feist46342ec2019-03-06 14:03:41 -0800120 }
Zhikui Renbf7cbc82020-07-02 08:44:00 -0700121
Yong Li10306bd2020-04-21 16:08:28 +0800122 pair->first.used = true;
123 pair->first.level = threshold.level;
124 pair->first.direction = threshold.direction;
Zhikui Renbf7cbc82020-07-02 08:44:00 -0700125 pair->first.assert = assert;
James Feist43d32fe2019-09-04 10:35:20 -0700126 pair->second.expires_from_now(boost::posix_time::seconds(waitTime));
Zhikui Renbf7cbc82020-07-02 08:44:00 -0700127 pair->second.async_wait([this, pair, threshold, assert,
128 assertValue](boost::system::error_code ec) {
129 pair->first.used = false;
James Feist43d32fe2019-09-04 10:35:20 -0700130
Zhikui Renbf7cbc82020-07-02 08:44:00 -0700131 if (ec == boost::asio::error::operation_aborted)
132 {
133 return; // we're being canceled
134 }
135 else if (ec)
136 {
137 std::cerr << "timer error: " << ec.message() << "\n";
138 return;
139 }
140 if (isPowerOn())
141 {
142 assertThresholds(sensor, assertValue, threshold.level,
143 threshold.direction, assert);
144 }
145 });
James Feist46342ec2019-03-06 14:03:41 -0800146 }
147
James Feist43d32fe2019-09-04 10:35:20 -0700148 boost::asio::io_service& io;
149 std::list<TimerPair> timers;
James Feist46342ec2019-03-06 14:03:41 -0800150 Sensor* sensor;
151};
152
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700153bool parseThresholdsFromConfig(
James Feistd8705872019-02-08 13:26:09 -0800154 const SensorData& sensorData,
155 std::vector<thresholds::Threshold>& thresholdVector,
156 const std::string* matchLabel = nullptr);
James Feist6714a252018-09-10 15:26:18 -0700157
James Feistd8705872019-02-08 13:26:09 -0800158bool parseThresholdsFromAttr(std::vector<thresholds::Threshold>& thresholds,
159 const std::string& inputPath,
Vijay Khemka86dea2b2019-06-06 11:14:37 -0700160 const double& scaleFactor,
161 const double& offset = 0);
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700162bool hasCriticalInterface(
James Feistd8705872019-02-08 13:26:09 -0800163 const std::vector<thresholds::Threshold>& thresholdVector);
James Feist251c7822018-09-12 12:54:15 -0700164
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700165bool hasWarningInterface(
James Feistd8705872019-02-08 13:26:09 -0800166 const std::vector<thresholds::Threshold>& thresholdVector);
James Feist6714a252018-09-10 15:26:18 -0700167
James Feistd8705872019-02-08 13:26:09 -0800168void persistThreshold(const std::string& baseInterface, const std::string& path,
169 const thresholds::Threshold& threshold,
James Feista222ba72019-03-01 15:57:51 -0800170 std::shared_ptr<sdbusplus::asio::connection>& conn,
Cheng C Yang6b1247a2020-03-09 23:48:39 +0800171 size_t thresholdCount, const std::string& label);
James Feist251c7822018-09-12 12:54:15 -0700172
Jae Hyun Yoo95b8a2d2019-02-25 20:15:09 -0800173void updateThresholds(Sensor* sensor);
James Feistdc6c55f2018-10-31 12:53:20 -0700174// returns false if a critical threshold has been crossed, true otherwise
James Feistd8705872019-02-08 13:26:09 -0800175bool checkThresholds(Sensor* sensor);
James Feist46342ec2019-03-06 14:03:41 -0800176void checkThresholdsPowerDelay(Sensor* sensor, ThresholdTimer& thresholdTimer);
Cheng C Yang6b1247a2020-03-09 23:48:39 +0800177
James Feist6714a252018-09-10 15:26:18 -0700178} // namespace thresholds