blob: 559f4dfc2ae563bd9211a06475147314f7283e95 [file] [log] [blame]
James Feist6714a252018-09-10 15:26:18 -07001#pragma once
Ed Tanous8a57ec02020-10-09 12:46:52 -07002#include <Utils.hpp>
James Feist8086aba2020-08-25 16:00:59 -07003#include <boost/asio/deadline_timer.hpp>
James Feist46342ec2019-03-06 14:03:41 -08004#include <boost/asio/io_service.hpp>
James Feist38fb5982020-05-28 10:09:54 -07005#include <nlohmann/json.hpp>
6
Patrick Venturefd6ba732019-10-31 14:27:39 -07007#include <list>
8#include <memory>
Patrick Venturefd6ba732019-10-31 14:27:39 -07009#include <string>
10#include <utility>
11#include <vector>
James Feist6714a252018-09-10 15:26:18 -070012
James Feist251c7822018-09-12 12:54:15 -070013struct Sensor;
James Feist6714a252018-09-10 15:26:18 -070014namespace thresholds
15{
16enum Level
17{
18 WARNING,
19 CRITICAL
20};
21enum Direction
22{
23 HIGH,
24 LOW
25};
26struct Threshold
27{
James Feistd8705872019-02-08 13:26:09 -080028 Threshold(const Level& lev, const Direction& dir, const double& val,
James Feist6714a252018-09-10 15:26:18 -070029 bool write = true) :
30 level(lev),
31 direction(dir), value(val), writeable(write)
James Feist38fb5982020-05-28 10:09:54 -070032 {}
James Feist6714a252018-09-10 15:26:18 -070033 Level level;
34 Direction direction;
35 double value;
36 bool writeable;
Jae Hyun Yoo95b8a2d2019-02-25 20:15:09 -080037
38 bool operator==(const Threshold& rhs) const
39 {
40 return (level == rhs.level && direction == rhs.direction &&
41 value == rhs.value);
42 }
James Feist6714a252018-09-10 15:26:18 -070043};
44
Zhikui Ren59b8b9e2020-06-26 18:34:22 -070045void assertThresholds(Sensor* sensor, double assertValue,
46 thresholds::Level level, thresholds::Direction direction,
47 bool assert);
James Feist46342ec2019-03-06 14:03:41 -080048
Yong Li10306bd2020-04-21 16:08:28 +080049struct TimerUsed
50{
51 bool used;
52 Level level;
53 Direction direction;
Zhikui Renbf7cbc82020-07-02 08:44:00 -070054 bool assert;
Yong Li10306bd2020-04-21 16:08:28 +080055};
56
57using TimerPair = std::pair<struct TimerUsed, boost::asio::deadline_timer>;
James Feist43d32fe2019-09-04 10:35:20 -070058
James Feist46342ec2019-03-06 14:03:41 -080059struct ThresholdTimer
60{
61
James Feist43d32fe2019-09-04 10:35:20 -070062 ThresholdTimer(boost::asio::io_service& ioService, Sensor* sensor) :
63 io(ioService), sensor(sensor)
James Feist38fb5982020-05-28 10:09:54 -070064 {}
James Feist46342ec2019-03-06 14:03:41 -080065
Zhikui Renbf7cbc82020-07-02 08:44:00 -070066 bool hasActiveTimer(const Threshold& threshold, bool assert)
67 {
68 for (TimerPair& timer : timers)
69 {
70 if (timer.first.used)
71 {
72 if ((timer.first.level == threshold.level) &&
73 (timer.first.direction == threshold.direction) &&
74 (timer.first.assert == assert))
75 {
76 return true;
77 }
78 }
79 }
80 return false;
81 }
82
83 void stopTimer(const Threshold& threshold, bool assert)
Yong Li10306bd2020-04-21 16:08:28 +080084 {
85 struct TimerUsed timerUsed = {};
86 for (TimerPair& timer : timers)
87 {
88 timerUsed = timer.first;
89 if (timerUsed.used)
90 {
91 if ((timerUsed.level == threshold.level) &&
Zhikui Renbf7cbc82020-07-02 08:44:00 -070092 (timerUsed.direction == threshold.direction) &&
93 (timerUsed.assert == assert))
Yong Li10306bd2020-04-21 16:08:28 +080094 {
95 timer.second.cancel();
96 }
97 }
98 }
99 }
100
Zhikui Renbf7cbc82020-07-02 08:44:00 -0700101 void startTimer(const Threshold& threshold, bool assert, double assertValue)
James Feist46342ec2019-03-06 14:03:41 -0800102 {
Yong Li10306bd2020-04-21 16:08:28 +0800103 struct TimerUsed timerUsed = {};
James Feist43d32fe2019-09-04 10:35:20 -0700104 constexpr const size_t waitTime = 5;
105 TimerPair* pair = nullptr;
James Feist46342ec2019-03-06 14:03:41 -0800106
James Feist43d32fe2019-09-04 10:35:20 -0700107 for (TimerPair& timer : timers)
James Feist46342ec2019-03-06 14:03:41 -0800108 {
Yong Li10306bd2020-04-21 16:08:28 +0800109 if (!timer.first.used)
James Feist43d32fe2019-09-04 10:35:20 -0700110 {
111 pair = &timer;
112 break;
113 }
James Feist46342ec2019-03-06 14:03:41 -0800114 }
James Feist43d32fe2019-09-04 10:35:20 -0700115 if (pair == nullptr)
James Feist46342ec2019-03-06 14:03:41 -0800116 {
Yong Li10306bd2020-04-21 16:08:28 +0800117 pair = &timers.emplace_back(timerUsed,
118 boost::asio::deadline_timer(io));
James Feist46342ec2019-03-06 14:03:41 -0800119 }
Zhikui Renbf7cbc82020-07-02 08:44:00 -0700120
Yong Li10306bd2020-04-21 16:08:28 +0800121 pair->first.used = true;
122 pair->first.level = threshold.level;
123 pair->first.direction = threshold.direction;
Zhikui Renbf7cbc82020-07-02 08:44:00 -0700124 pair->first.assert = assert;
James Feist43d32fe2019-09-04 10:35:20 -0700125 pair->second.expires_from_now(boost::posix_time::seconds(waitTime));
Zhikui Renbf7cbc82020-07-02 08:44:00 -0700126 pair->second.async_wait([this, pair, threshold, assert,
127 assertValue](boost::system::error_code ec) {
128 pair->first.used = false;
James Feist43d32fe2019-09-04 10:35:20 -0700129
Zhikui Renbf7cbc82020-07-02 08:44:00 -0700130 if (ec == boost::asio::error::operation_aborted)
131 {
132 return; // we're being canceled
133 }
Ed Tanous8a57ec02020-10-09 12:46:52 -0700134 if (ec)
Zhikui Renbf7cbc82020-07-02 08:44:00 -0700135 {
Ed Tanous8a57ec02020-10-09 12:46:52 -0700136
Zhikui Renbf7cbc82020-07-02 08:44:00 -0700137 std::cerr << "timer error: " << ec.message() << "\n";
Ed Tanous8a57ec02020-10-09 12:46:52 -0700138
Zhikui Renbf7cbc82020-07-02 08:44:00 -0700139 return;
140 }
141 if (isPowerOn())
142 {
143 assertThresholds(sensor, assertValue, threshold.level,
144 threshold.direction, assert);
145 }
146 });
James Feist46342ec2019-03-06 14:03:41 -0800147 }
148
James Feist43d32fe2019-09-04 10:35:20 -0700149 boost::asio::io_service& io;
150 std::list<TimerPair> timers;
James Feist46342ec2019-03-06 14:03:41 -0800151 Sensor* sensor;
152};
153
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700154bool parseThresholdsFromConfig(
James Feistd8705872019-02-08 13:26:09 -0800155 const SensorData& sensorData,
156 std::vector<thresholds::Threshold>& thresholdVector,
157 const std::string* matchLabel = nullptr);
James Feist6714a252018-09-10 15:26:18 -0700158
James Feistd8705872019-02-08 13:26:09 -0800159bool parseThresholdsFromAttr(std::vector<thresholds::Threshold>& thresholds,
160 const std::string& inputPath,
Vijay Khemka86dea2b2019-06-06 11:14:37 -0700161 const double& scaleFactor,
162 const double& offset = 0);
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700163bool hasCriticalInterface(
James Feistd8705872019-02-08 13:26:09 -0800164 const std::vector<thresholds::Threshold>& thresholdVector);
James Feist251c7822018-09-12 12:54:15 -0700165
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700166bool hasWarningInterface(
James Feistd8705872019-02-08 13:26:09 -0800167 const std::vector<thresholds::Threshold>& thresholdVector);
James Feist6714a252018-09-10 15:26:18 -0700168
James Feistd8705872019-02-08 13:26:09 -0800169void persistThreshold(const std::string& baseInterface, const std::string& path,
170 const thresholds::Threshold& threshold,
James Feista222ba72019-03-01 15:57:51 -0800171 std::shared_ptr<sdbusplus::asio::connection>& conn,
Cheng C Yang6b1247a2020-03-09 23:48:39 +0800172 size_t thresholdCount, const std::string& label);
James Feist251c7822018-09-12 12:54:15 -0700173
Jae Hyun Yoo95b8a2d2019-02-25 20:15:09 -0800174void updateThresholds(Sensor* sensor);
James Feistdc6c55f2018-10-31 12:53:20 -0700175// returns false if a critical threshold has been crossed, true otherwise
James Feistd8705872019-02-08 13:26:09 -0800176bool checkThresholds(Sensor* sensor);
James Feist46342ec2019-03-06 14:03:41 -0800177void checkThresholdsPowerDelay(Sensor* sensor, ThresholdTimer& thresholdTimer);
Cheng C Yang6b1247a2020-03-09 23:48:39 +0800178
James Feist6714a252018-09-10 15:26:18 -0700179} // namespace thresholds