blob: 9934d8af8f08b0fa0bc35f88cef97d89030828c5 [file] [log] [blame]
Brad Bishope55ef3d2016-12-19 09:12:40 -05001/**
2 * Copyright © 2016 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include <iostream>
17#include <memory>
Brad Bishop9c7b6e02016-12-19 12:43:36 -050018#include <cstring>
19#include <cstdlib>
20#include <chrono>
Brad Bishop74aa4dd2017-01-06 09:50:31 -050021#include <algorithm>
Brad Bishope55ef3d2016-12-19 09:12:40 -050022#include "sensorset.hpp"
Brad Bishope55ef3d2016-12-19 09:12:40 -050023#include "hwmon.hpp"
24#include "sysfs.hpp"
Brad Bishopd499ca62016-12-19 09:24:50 -050025#include "mainloop.hpp"
Brad Bishopab795a12017-01-05 20:50:49 -050026#include "util.hpp"
Brad Bishopf3df6b42017-01-06 10:14:09 -050027#include "env.hpp"
Brad Bishope0b7d052017-01-06 15:30:23 -050028#include "thresholds.hpp"
Brad Bishope55ef3d2016-12-19 09:12:40 -050029
Brad Bishop9c7b6e02016-12-19 12:43:36 -050030using namespace std::literals::chrono_literals;
31
Brad Bishop74aa4dd2017-01-06 09:50:31 -050032static constexpr auto typeAttrMap =
33{
34 // 1 - hwmon class
35 // 2 - unit
36 // 3 - sysfs scaling factor
37 std::make_tuple(
38 hwmon::type::ctemp,
39 ValueInterface::Unit::DegreesC,
40 -3),
41 std::make_tuple(
42 hwmon::type::cfan,
43 ValueInterface::Unit::RPMS,
44 0),
45 std::make_tuple(
46 hwmon::type::cvolt,
47 ValueInterface::Unit::Volts,
48 -3),
49};
50
51auto getHwmonType(decltype(typeAttrMap)::const_reference attrs)
52{
53 return std::get<0>(attrs);
54}
55
56auto getUnit(decltype(typeAttrMap)::const_reference attrs)
57{
58 return std::get<1>(attrs);
59}
60
61auto getScale(decltype(typeAttrMap)::const_reference attrs)
62{
63 return std::get<2>(attrs);
64}
65
Brad Bishope9fdee02017-01-06 10:43:29 -050066auto addValue(const SensorSet::key_type& sensor,
67 const std::string& sysfsRoot, ObjectInfo& info)
68{
69 // Get the initial value for the value interface.
70 auto& bus = *std::get<sdbusplus::bus::bus*>(info);
71 auto& obj = std::get<Object>(info);
72 auto& objPath = std::get<std::string>(info);
73
74 auto sysfsPath = make_sysfs_path(
75 sysfsRoot,
76 sensor.first,
77 sensor.second,
78 hwmon::entry::input);
79 int val = 0;
80 read_sysfs(sysfsPath, val);
81
82 auto iface = std::make_shared<ValueObject>(bus, objPath.c_str());
83 iface->value(val);
84
85 // *INDENT-OFF*
86 const auto& attrs = std::find_if(
87 typeAttrMap.begin(),
88 typeAttrMap.end(),
89 [&](const auto & e)
90 {
91 return sensor.first == getHwmonType(e);
92 });
93 // *INDENT-ON*
94
95 if (attrs != typeAttrMap.end())
96 {
97 iface->unit(getUnit(*attrs));
98 iface->scale(getScale(*attrs));
99 }
100
101 obj[InterfaceType::VALUE] = iface;
102 return iface;
103}
104
Brad Bishopb9e2b072016-12-19 13:47:10 -0500105MainLoop::MainLoop(
Brad Bishop9c7b6e02016-12-19 12:43:36 -0500106 sdbusplus::bus::bus&& bus,
Brad Bishopb9e2b072016-12-19 13:47:10 -0500107 const std::string& path,
108 const char* prefix,
109 const char* root)
Brad Bishop9c7b6e02016-12-19 12:43:36 -0500110 : _bus(std::move(bus)),
111 _manager(sdbusplus::server::manager::manager(_bus, root)),
112 _shutdown(false),
Brad Bishopb9e2b072016-12-19 13:47:10 -0500113 _path(path),
114 _prefix(prefix),
Brad Bishop3c344d32017-01-05 11:48:39 -0500115 _root(root),
116 state()
Brad Bishopd499ca62016-12-19 09:24:50 -0500117{
Brad Bishop9c7b6e02016-12-19 12:43:36 -0500118 if (_path.back() == '/')
119 {
120 _path.pop_back();
121 }
Brad Bishopd499ca62016-12-19 09:24:50 -0500122}
123
124void MainLoop::shutdown() noexcept
125{
126 _shutdown = true;
127}
128
129void MainLoop::run()
Brad Bishope55ef3d2016-12-19 09:12:40 -0500130{
131 // Check sysfs for available sensors.
Brad Bishopd499ca62016-12-19 09:24:50 -0500132 auto sensors = std::make_unique<SensorSet>(_path);
Brad Bishope55ef3d2016-12-19 09:12:40 -0500133
Brad Bishop75b4ab82017-01-06 09:33:50 -0500134 for (auto& i : *sensors)
135 {
Brad Bishopf3df6b42017-01-06 10:14:09 -0500136 // Get sensor configuration from the environment.
137
Brad Bishop73831cd2017-01-06 09:37:22 -0500138 // Ignore inputs without a label.
Brad Bishopf3df6b42017-01-06 10:14:09 -0500139 auto label = getEnv("LABEL", i.first);
Brad Bishop73831cd2017-01-06 09:37:22 -0500140 if (label.empty())
141 {
142 continue;
143 }
144
Brad Bishop075f7a22017-01-06 09:45:08 -0500145 std::string objectPath{_root};
Brad Bishop075f7a22017-01-06 09:45:08 -0500146 objectPath.append("/");
147 objectPath.append(i.first.first);
148 objectPath.append("/");
149 objectPath.append(label);
150
Brad Bishopf7426cf2017-01-06 15:36:43 -0500151 ObjectInfo info(&_bus, std::move(objectPath), Object());
Brad Bishope9fdee02017-01-06 10:43:29 -0500152 auto valueInterface = addValue(i.first, _path, info);
Brad Bishope0b7d052017-01-06 15:30:23 -0500153 auto sensorValue = valueInterface->value();
154 addThreshold<WarningObject>(i.first, sensorValue, info);
155 addThreshold<CriticalObject>(i.first, sensorValue, info);
Brad Bishop075f7a22017-01-06 09:45:08 -0500156
157 auto value = std::make_tuple(
158 std::move(i.second),
159 std::move(label),
Brad Bishopf7426cf2017-01-06 15:36:43 -0500160 std::move(info));
Brad Bishop73831cd2017-01-06 09:37:22 -0500161
Brad Bishop75b4ab82017-01-06 09:33:50 -0500162 state[std::move(i.first)] = std::move(value);
163 }
164
Brad Bishop9c7b6e02016-12-19 12:43:36 -0500165 {
Brad Bishopab795a12017-01-05 20:50:49 -0500166 auto copy = std::unique_ptr<char, phosphor::utility::Free<char>>(strdup(
167 _path.c_str()));
Brad Bishop9c7b6e02016-12-19 12:43:36 -0500168 auto busname = std::string(_prefix) + '.' + basename(copy.get());
169 _bus.request_name(busname.c_str());
170 }
171
Brad Bishope55ef3d2016-12-19 09:12:40 -0500172 // TODO: Issue#3 - Need to make calls to the dbus sensor cache here to
173 // ensure the objects all exist?
174
175 // Polling loop.
Brad Bishopd499ca62016-12-19 09:24:50 -0500176 while (!_shutdown)
Brad Bishope55ef3d2016-12-19 09:12:40 -0500177 {
178 // Iterate through all the sensors.
Brad Bishop75b4ab82017-01-06 09:33:50 -0500179 for (auto& i : state)
Brad Bishope55ef3d2016-12-19 09:12:40 -0500180 {
Brad Bishop75b4ab82017-01-06 09:33:50 -0500181 auto& attrs = std::get<0>(i.second);
182 if (attrs.find(hwmon::entry::input) != attrs.end())
Brad Bishope55ef3d2016-12-19 09:12:40 -0500183 {
184 // Read value from sensor.
185 int value = 0;
Brad Bishopd499ca62016-12-19 09:24:50 -0500186 read_sysfs(make_sysfs_path(_path,
Brad Bishope55ef3d2016-12-19 09:12:40 -0500187 i.first.first, i.first.second,
188 hwmon::entry::input),
189 value);
190
Brad Bishopf7426cf2017-01-06 15:36:43 -0500191 auto& objInfo = std::get<ObjectInfo>(i.second);
192 auto& obj = std::get<Object>(objInfo);
Brad Bishopdddb7152017-01-06 09:54:23 -0500193
Brad Bishope0b7d052017-01-06 15:30:23 -0500194 for (auto& iface : obj)
Brad Bishopdddb7152017-01-06 09:54:23 -0500195 {
Brad Bishope0b7d052017-01-06 15:30:23 -0500196 auto valueIface = std::shared_ptr<ValueObject>();
197 auto warnIface = std::shared_ptr<WarningObject>();
198 auto critIface = std::shared_ptr<CriticalObject>();
199
200 switch (iface.first)
201 {
202 case InterfaceType::VALUE:
203 valueIface = std::experimental::any_cast<std::shared_ptr<ValueObject>>
204 (iface.second);
205 valueIface->value(value);
206 break;
207 case InterfaceType::WARN:
208 checkThresholds<WarningObject>(iface.second, value);
209 break;
210 case InterfaceType::CRIT:
211 checkThresholds<CriticalObject>(iface.second, value);
212 break;
213 default:
214 break;
215 }
Brad Bishopdddb7152017-01-06 09:54:23 -0500216 }
Brad Bishope55ef3d2016-12-19 09:12:40 -0500217 }
218 }
219
Brad Bishop9c7b6e02016-12-19 12:43:36 -0500220 // Respond to DBus
221 _bus.process_discard();
222
Brad Bishope55ef3d2016-12-19 09:12:40 -0500223 // Sleep until next interval.
224 // TODO: Issue#5 - Make this configurable.
225 // TODO: Issue#6 - Optionally look at polling interval sysfs entry.
Brad Bishop9c7b6e02016-12-19 12:43:36 -0500226 _bus.wait((1000000us).count());
Brad Bishope55ef3d2016-12-19 09:12:40 -0500227
228 // TODO: Issue#7 - Should probably periodically check the SensorSet
229 // for new entries.
230 }
Brad Bishope55ef3d2016-12-19 09:12:40 -0500231}
232
233// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4