blob: fade0e6233dfda252be8f4a26a6285bfd7a05ae5 [file] [log] [blame]
James Feist6714a252018-09-10 15:26:18 -07001/*
2// Copyright (c) 2017 Intel 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
17#include <Utils.hpp>
18#include <boost/algorithm/string/predicate.hpp>
James Feist24f02f22019-04-15 11:05:39 -070019#include <filesystem>
James Feist6714a252018-09-10 15:26:18 -070020#include <fstream>
21#include <regex>
22#include <sdbusplus/asio/connection.hpp>
James Feist82bac4c2019-03-11 11:16:53 -070023#include <sdbusplus/asio/object_server.hpp>
James Feist6714a252018-09-10 15:26:18 -070024#include <sdbusplus/bus/match.hpp>
25
James Feistcf3bce62019-01-08 10:07:19 -080026namespace fs = std::filesystem;
James Feist6714a252018-09-10 15:26:18 -070027
James Feist6ef20402019-01-07 16:45:08 -080028static bool powerStatusOn = false;
James Feistfc94b212019-02-06 16:14:51 -080029static bool biosHasPost = false;
James Feist58295ad2019-05-30 15:01:41 -070030
James Feist6ef20402019-01-07 16:45:08 -080031static std::unique_ptr<sdbusplus::bus::match::match> powerMatch = nullptr;
James Feist52497fd2019-06-07 13:01:33 -070032static std::unique_ptr<sdbusplus::bus::match::match> postMatch = nullptr;
James Feist71d31b22019-01-02 16:57:54 -080033
James Feist6714a252018-09-10 15:26:18 -070034bool getSensorConfiguration(
35 const std::string& type,
36 const std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
37 ManagedObjectType& resp, bool useCache)
38{
39 static ManagedObjectType managedObj;
40
41 if (!useCache)
42 {
43 managedObj.clear();
44 sdbusplus::message::message getManagedObjects =
45 dbusConnection->new_method_call(
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -070046 entityManagerName, "/", "org.freedesktop.DBus.ObjectManager",
James Feist6714a252018-09-10 15:26:18 -070047 "GetManagedObjects");
48 bool err = false;
49 try
50 {
51 sdbusplus::message::message reply =
52 dbusConnection->call(getManagedObjects);
Yoo, Jae Hyun0e022052018-10-15 14:05:37 -070053 reply.read(managedObj);
James Feist6714a252018-09-10 15:26:18 -070054 }
55 catch (const sdbusplus::exception::exception&)
56 {
57 err = true;
58 }
59
60 if (err)
61 {
62 std::cerr << "Error communicating to entity manager\n";
63 return false;
64 }
65 }
66 for (const auto& pathPair : managedObj)
67 {
68 std::vector<boost::container::flat_map<std::string, BasicVariantType>>
69 sensorData;
70 bool correctType = false;
71 for (const auto& entry : pathPair.second)
72 {
73 if (boost::starts_with(entry.first, type))
74 {
75 correctType = true;
76 break;
77 }
78 }
79 if (correctType)
80 {
81 resp.emplace(pathPair);
82 }
83 }
84 return true;
85}
86
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -070087bool findFiles(const fs::path dirPath, const std::string& matchString,
88 std::vector<fs::path>& foundPaths, unsigned int symlinkDepth)
James Feist6714a252018-09-10 15:26:18 -070089{
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -070090 if (!fs::exists(dirPath))
James Feist6714a252018-09-10 15:26:18 -070091 return false;
92
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -070093 std::regex search(matchString);
James Feist6714a252018-09-10 15:26:18 -070094 std::smatch match;
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -070095 for (auto& p : fs::recursive_directory_iterator(dirPath))
James Feist6714a252018-09-10 15:26:18 -070096 {
97 std::string path = p.path().string();
98 if (!is_directory(p))
99 {
100 if (std::regex_search(path, match, search))
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700101 foundPaths.emplace_back(p.path());
James Feist6714a252018-09-10 15:26:18 -0700102 }
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700103 else if (is_symlink(p) && symlinkDepth)
James Feist6714a252018-09-10 15:26:18 -0700104 {
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700105 findFiles(p.path(), matchString, foundPaths, symlinkDepth - 1);
James Feist6714a252018-09-10 15:26:18 -0700106 }
107 }
108 return true;
109}
110
James Feist71d31b22019-01-02 16:57:54 -0800111bool isPowerOn(void)
James Feist6714a252018-09-10 15:26:18 -0700112{
James Feist71d31b22019-01-02 16:57:54 -0800113 if (!powerMatch)
James Feist6714a252018-09-10 15:26:18 -0700114 {
James Feist71d31b22019-01-02 16:57:54 -0800115 throw std::runtime_error("Power Match Not Created");
James Feist6714a252018-09-10 15:26:18 -0700116 }
James Feist71d31b22019-01-02 16:57:54 -0800117 return powerStatusOn;
118}
119
James Feistfc94b212019-02-06 16:14:51 -0800120bool hasBiosPost(void)
121{
James Feist52497fd2019-06-07 13:01:33 -0700122 if (!postMatch)
James Feistfc94b212019-02-06 16:14:51 -0800123 {
James Feist52497fd2019-06-07 13:01:33 -0700124 throw std::runtime_error("Post Match Not Created");
James Feistfc94b212019-02-06 16:14:51 -0800125 }
126 return biosHasPost;
127}
128
James Feist71d31b22019-01-02 16:57:54 -0800129void setupPowerMatch(const std::shared_ptr<sdbusplus::asio::connection>& conn)
130{
James Feist6714a252018-09-10 15:26:18 -0700131 // create a match for powergood changes, first time do a method call to
James Feist71d31b22019-01-02 16:57:54 -0800132 // cache the correct value
James Feist52497fd2019-06-07 13:01:33 -0700133 if (powerMatch)
134 {
135 return;
136 }
James Feist6714a252018-09-10 15:26:18 -0700137
138 powerMatch = std::make_unique<sdbusplus::bus::match::match>(
139 static_cast<sdbusplus::bus::bus&>(*conn),
James Feist52497fd2019-06-07 13:01:33 -0700140 "type='signal',interface='" + std::string(properties::interface) +
141 "',path='" + std::string(power::path) + "',arg0='" +
142 std::string(power::interface) + "'",
143 [](sdbusplus::message::message& message) {
144 std::string objectName;
145 boost::container::flat_map<std::string, std::variant<std::string>>
146 values;
147 message.read(objectName, values);
148 auto findState = values.find(power::property);
149 if (findState != values.end())
James Feist6714a252018-09-10 15:26:18 -0700150 {
James Feist52497fd2019-06-07 13:01:33 -0700151 powerStatusOn = boost::ends_with(
152 std::get<std::string>(findState->second), "Running");
James Feist6714a252018-09-10 15:26:18 -0700153 }
James Feist52497fd2019-06-07 13:01:33 -0700154 });
155
156 postMatch = std::make_unique<sdbusplus::bus::match::match>(
157 static_cast<sdbusplus::bus::bus&>(*conn),
158 "type='signal',interface='" + std::string(properties::interface) +
159 "',path='" + std::string(post::path) + "',arg0='" +
160 std::string(post::interface) + "'",
161 [](sdbusplus::message::message& message) {
162 std::string objectName;
163 boost::container::flat_map<std::string, std::variant<std::string>>
164 values;
165 message.read(objectName, values);
166 auto findState = values.find(post::property);
167 if (findState != values.end())
168 {
169 biosHasPost =
170 std::get<std::string>(findState->second) != "Inactive";
171 }
172 });
James Feistfc94b212019-02-06 16:14:51 -0800173
174 conn->async_method_call(
175 [](boost::system::error_code ec,
James Feist52497fd2019-06-07 13:01:33 -0700176 const std::variant<std::string>& state) {
James Feistfc94b212019-02-06 16:14:51 -0800177 if (ec)
178 {
James Feistcee4ef22019-04-04 11:04:08 -0700179 // we commonly come up before power control, we'll capture the
180 // property change later
James Feistfc94b212019-02-06 16:14:51 -0800181 return;
182 }
James Feist52497fd2019-06-07 13:01:33 -0700183 powerStatusOn =
184 boost::ends_with(std::get<std::string>(state), "Running");
James Feistfc94b212019-02-06 16:14:51 -0800185 },
James Feist52497fd2019-06-07 13:01:33 -0700186 power::busname, power::path, properties::interface, properties::get,
187 power::interface, power::property);
188
189 conn->async_method_call(
190 [](boost::system::error_code ec,
191 const std::variant<std::string>& state) {
192 if (ec)
193 {
194 // we commonly come up before power control, we'll capture the
195 // property change later
196 return;
197 }
198 biosHasPost = std::get<std::string>(state) != "Inactive";
199 },
200 post::busname, post::path, properties::interface, properties::get,
201 post::interface, post::property);
James Feist3f0e8762018-11-27 11:30:42 -0800202}
James Feist87d713a2018-12-06 16:06:24 -0800203
204// replaces limits if MinReading and MaxReading are found.
205void findLimits(std::pair<double, double>& limits,
206 const SensorBaseConfiguration* data)
207{
208 if (!data)
209 {
210 return;
211 }
212 auto maxFind = data->second.find("MaxReading");
213 auto minFind = data->second.find("MinReading");
214
215 if (minFind != data->second.end())
216 {
James Feist3eb82622019-02-08 13:10:22 -0800217 limits.first = std::visit(VariantToDoubleVisitor(), minFind->second);
James Feist87d713a2018-12-06 16:06:24 -0800218 }
219 if (maxFind != data->second.end())
220 {
James Feist3eb82622019-02-08 13:10:22 -0800221 limits.second = std::visit(VariantToDoubleVisitor(), maxFind->second);
James Feist87d713a2018-12-06 16:06:24 -0800222 }
James Feistfc94b212019-02-06 16:14:51 -0800223}
James Feist82bac4c2019-03-11 11:16:53 -0700224
225void createAssociation(
226 std::shared_ptr<sdbusplus::asio::dbus_interface>& association,
227 const std::string& path)
228{
229 if (association)
230 {
James Feistd2543f82019-04-09 11:10:06 -0700231 std::filesystem::path p(path);
232
James Feist82bac4c2019-03-11 11:16:53 -0700233 std::vector<Association> associations;
James Feistd2543f82019-04-09 11:10:06 -0700234 associations.push_back(
James Feistd8bd5622019-06-26 12:09:05 -0700235 Association("chassis", "all_sensors", p.parent_path().string()));
James Feist82bac4c2019-03-11 11:16:53 -0700236 association->register_property("associations", associations);
237 association->initialize();
238 }
239}