blob: dfe82ef8e87d5175e1cacb1ce54f39a547e4d98e [file] [log] [blame]
George Hunga66f2b92020-05-19 15:52:33 +08001From 58eec8f1f80e274ff669bd19c00b8f1ea8ceae0f Mon Sep 17 00:00:00 2001
2From: Duke Du <Duke.Du@quantatw.com>
3Date: Mon, 18 May 2020 19:45:27 +0800
4Subject: [PATCH] lev-add-poweron-monitor-feature
5
6---
7 Makefile.am | 2 ++
8 mainloop.cpp | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9 sensor.cpp | 11 ++++++-
10 sensor.hpp | 13 ++++++++
11 thresholds.hpp | 2 --
12 5 files changed, 126 insertions(+), 3 deletions(-)
13
14diff --git a/Makefile.am b/Makefile.am
15index 378c565..5fa230a 100644
16--- a/Makefile.am
17+++ b/Makefile.am
18@@ -46,6 +46,7 @@ libhwmon_la_LIBADD = \
19 $(SDEVENTPLUS_LIBS) \
20 $(PHOSPHOR_DBUS_INTERFACES_LIBS) \
21 $(PHOSPHOR_LOGGING_LIBS) \
22+ $(PTHREAD_LIBS) \
23 $(GPIOPLUS_LIBS) \
24 $(STDPLUS_LIBS) \
25 $(CODE_COVERAGE_LIBS)
26@@ -54,6 +55,7 @@ libhwmon_la_CXXFLAGS = \
27 $(SDEVENTPLUS_CFLAGS) \
28 $(PHOSPHOR_DBUS_INTERFACES_CFLAGS) \
29 $(PHOSPHOR_LOGGING_CFLAGS) \
30+ $(PTHREAD_CFLAGS) \
31 $(STDPLUS_CFLAGS) \
32 $(CODE_COVERAGE_CXXFLAGS)
33
34diff --git a/mainloop.cpp b/mainloop.cpp
35index bd334a0..1769e94 100644
36--- a/mainloop.cpp
37+++ b/mainloop.cpp
38@@ -39,6 +39,12 @@
39 #include <string>
40 #include <unordered_set>
41 #include <xyz/openbmc_project/Sensor/Device/error.hpp>
42+#include <boost/container/flat_map.hpp>
43+#include <boost/algorithm/string/predicate.hpp>
44+#include <sdbusplus/asio/connection.hpp>
45+#include <sdbusplus/asio/object_server.hpp>
46+#include <sdbusplus/message/types.hpp>
47+#include <sdbusplus/timer.hpp>
48
49 using namespace phosphor::logging;
50
51@@ -74,6 +80,12 @@ decltype(
52 Thresholds<CriticalObject>::alarmHi) Thresholds<CriticalObject>::alarmHi =
53 &CriticalObject::criticalAlarmHigh;
54
55+static std::unique_ptr<phosphor::Timer> cacheTimer = nullptr;
56+static std::unique_ptr<sdbusplus::bus::match::match> powerMatch = nullptr;
57+static bool powerStatusOn = false;
58+static boost::asio::io_service io;
59+static auto conn = std::make_shared<sdbusplus::asio::connection>(io);
60+
61 void updateSensorInterfaces(InterfaceMap& ifaces, int64_t value)
62 {
63 for (auto& iface : ifaces)
64@@ -101,6 +113,83 @@ void updateSensorInterfaces(InterfaceMap& ifaces, int64_t value)
65 }
66 }
67
68+void powerStatusSet()
69+{
70+ powerStatusOn = true;
71+ return;
72+}
73+
74+void createTimer()
75+{
76+ if (cacheTimer == nullptr)
77+ {
78+ cacheTimer = std::make_unique<phosphor::Timer>(powerStatusSet);
79+ }
80+}
81+
82+bool isPowerOn(void)
83+{
84+ if (!powerMatch)
85+ {
86+ throw std::runtime_error("Power Match Not Created");
87+ }
88+ return powerStatusOn;
89+}
90+
91+void setupPowerMatch(sdbusplus::bus::bus& bus)
92+{
93+ if (powerMatch)
94+ {
95+ return;
96+ }
97+
98+ powerMatch = std::make_unique<sdbusplus::bus::match::match>(
99+ bus,
100+ "type='signal',interface='org.freedesktop.DBus.Properties',path='/xyz/"
101+ "openbmc_project/state/"
102+ "host0',arg0='xyz.openbmc_project.State.Host'",
103+ [](sdbusplus::message::message& message) {
104+ std::string objectName;
105+ boost::container::flat_map<std::string, std::variant<std::string>>
106+ values;
107+ message.read(objectName, values);
108+ auto findState = values.find("CurrentHostState");
109+ if (findState != values.end())
110+ {
111+ bool on = boost::ends_with(
112+ std::get<std::string>(findState->second), "Running");
113+ if (!on)
114+ {
115+ cacheTimer->stop();
116+ powerStatusOn = false;
117+ return;
118+ }
119+ cacheTimer->start(std::chrono::duration_cast<std::chrono::microseconds>(
120+ std::chrono::seconds(10)));
121+ }
122+ else {
123+ powerStatusOn = false;
124+ }
125+ });
126+
127+ conn->async_method_call(
128+ [](boost::system::error_code ec,
129+ const std::variant<std::string>& state) {
130+ if (ec)
131+ {
132+ return;
133+ }
134+ powerStatusOn =
135+ boost::ends_with(std::get<std::string>(state), "Running");
136+ },
137+ "xyz.openbmc_project.State.Host",
138+ "/xyz/openbmc_project/state/host0",
139+ "org.freedesktop.DBus.Properties", "Get",
140+ "xyz.openbmc_project.State.Host", "CurrentHostState");
141+
142+ createTimer();
143+}
144+
145 std::string MainLoop::getID(SensorSet::container_t::const_reference sensor)
146 {
147 std::string id;
148@@ -385,6 +474,7 @@ void MainLoop::init()
149 _interval = std::strtoull(interval.c_str(), NULL, 10);
150 }
151 }
152+ setupPowerMatch(_bus);
153 }
154
155 void MainLoop::read()
156@@ -429,6 +519,12 @@ void MainLoop::read()
157
158 try
159 {
160+ if(sensor->pwrOnMonitor() && !isPowerOn())
161+ {
162+ statusIface->functional(false);
163+ continue;
164+ }
165+
166 if (sensor->hasFaultFile())
167 {
168 auto fault = _ioAccess->read(sensorSysfsType, sensorSysfsNum,
169@@ -491,6 +587,11 @@ void MainLoop::read()
170 }
171 }
172
173+ if(sensor->pwrOnMonitor() && !isPowerOn())
174+ {
175+ statusIface->functional(false);
176+ continue;
177+ }
178 updateSensorInterfaces(obj, value);
179 }
180 catch (const std::system_error& e)
181diff --git a/sensor.cpp b/sensor.cpp
182index 145ba6c..93bbb03 100644
183--- a/sensor.cpp
184+++ b/sensor.cpp
185@@ -41,7 +41,7 @@ Sensor::Sensor(const SensorSet::key_type& sensor,
186 const hwmonio::HwmonIOInterface* ioAccess,
187 const std::string& devPath) :
188 _sensor(sensor),
189- _ioAccess(ioAccess), _devPath(devPath), _scale(0), _hasFaultFile(false)
190+ _ioAccess(ioAccess), _devPath(devPath), _scale(0), _hasFaultFile(false), _pwrOnMonitor(false)
191 {
192 auto chip = env::getEnv("GPIOCHIP", sensor);
193 auto access = env::getEnv("GPIO", sensor);
194@@ -70,6 +70,15 @@ Sensor::Sensor(const SensorSet::key_type& sensor,
195 auto senRmRCs = env::getEnv("REMOVERCS", sensor);
196 // Add sensor removal return codes defined per sensor
197 addRemoveRCs(senRmRCs);
198+
199+ auto pwrOnMon = env::getEnv("PWRONMON", sensor);
200+ if (!pwrOnMon.empty())
201+ {
202+ if (pwrOnMon == "ON")
203+ {
204+ _pwrOnMonitor = true;
205+ }
206+ }
207 }
208
209 void Sensor::addRemoveRCs(const std::string& rcList)
210diff --git a/sensor.hpp b/sensor.hpp
211index 4b2d281..369a252 100644
212--- a/sensor.hpp
213+++ b/sensor.hpp
214@@ -135,6 +135,16 @@ class Sensor
215 return _hasFaultFile;
216 }
217
218+ /**
219+ * @brief Get whether the sensor only need to be monitored in power on state or not.
220+ *
221+ * @return - Boolean on whether the sensor only need to be monitored in power on state
222+ */
223+ inline bool pwrOnMonitor(void) const
224+ {
225+ return _pwrOnMonitor;
226+ }
227+
228 private:
229 /** @brief Sensor object's identifiers */
230 SensorSet::key_type _sensor;
231@@ -156,6 +166,9 @@ class Sensor
232
233 /** @brief Tracks whether the sensor has a fault file or not. */
234 bool _hasFaultFile;
235+
236+ /** @brief Whether the sensor only need to be monitored in power on state or not. */
237+ bool _pwrOnMonitor;
238 };
239
240 /**
241diff --git a/thresholds.hpp b/thresholds.hpp
242index 4d2fcff..972a469 100644
243--- a/thresholds.hpp
244+++ b/thresholds.hpp
245@@ -101,8 +101,6 @@ auto addThreshold(const std::string& sensorType, const std::string& sensorID,
246 auto hi = stod(tHi) * std::pow(10, scale);
247 (*iface.*Thresholds<T>::setLo)(lo);
248 (*iface.*Thresholds<T>::setHi)(hi);
249- (*iface.*Thresholds<T>::alarmLo)(value <= lo);
250- (*iface.*Thresholds<T>::alarmHi)(value >= hi);
251 auto type = Thresholds<T>::type;
252 obj[type] = iface;
253 }
254--
2552.7.4
256