blob: 52f5d1de72d134544fbd877d5f220e01cf3da446 [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
James Feistcf3bce62019-01-08 10:07:19 -080017#include "filesystem.hpp"
18
James Feist6714a252018-09-10 15:26:18 -070019#include <Utils.hpp>
20#include <boost/algorithm/string/predicate.hpp>
James Feist6714a252018-09-10 15:26:18 -070021#include <fstream>
22#include <regex>
23#include <sdbusplus/asio/connection.hpp>
24#include <sdbusplus/bus/match.hpp>
25
James Feistcf3bce62019-01-08 10:07:19 -080026namespace fs = std::filesystem;
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -070027const static constexpr char* powerInterfaceName =
James Feist6714a252018-09-10 15:26:18 -070028 "xyz.openbmc_project.Chassis.Control.Power";
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -070029const static constexpr char* powerObjectName =
James Feist6714a252018-09-10 15:26:18 -070030 "/xyz/openbmc_project/Chassis/Control/Power0";
31
James Feist6ef20402019-01-07 16:45:08 -080032static bool powerStatusOn = false;
33static std::unique_ptr<sdbusplus::bus::match::match> powerMatch = nullptr;
James Feist71d31b22019-01-02 16:57:54 -080034
James Feist6714a252018-09-10 15:26:18 -070035bool getSensorConfiguration(
36 const std::string& type,
37 const std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
38 ManagedObjectType& resp, bool useCache)
39{
40 static ManagedObjectType managedObj;
41
42 if (!useCache)
43 {
44 managedObj.clear();
45 sdbusplus::message::message getManagedObjects =
46 dbusConnection->new_method_call(
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -070047 entityManagerName, "/", "org.freedesktop.DBus.ObjectManager",
James Feist6714a252018-09-10 15:26:18 -070048 "GetManagedObjects");
49 bool err = false;
50 try
51 {
52 sdbusplus::message::message reply =
53 dbusConnection->call(getManagedObjects);
Yoo, Jae Hyun0e022052018-10-15 14:05:37 -070054 reply.read(managedObj);
James Feist6714a252018-09-10 15:26:18 -070055 }
56 catch (const sdbusplus::exception::exception&)
57 {
58 err = true;
59 }
60
61 if (err)
62 {
63 std::cerr << "Error communicating to entity manager\n";
64 return false;
65 }
66 }
67 for (const auto& pathPair : managedObj)
68 {
69 std::vector<boost::container::flat_map<std::string, BasicVariantType>>
70 sensorData;
71 bool correctType = false;
72 for (const auto& entry : pathPair.second)
73 {
74 if (boost::starts_with(entry.first, type))
75 {
76 correctType = true;
77 break;
78 }
79 }
80 if (correctType)
81 {
82 resp.emplace(pathPair);
83 }
84 }
85 return true;
86}
87
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -070088bool findFiles(const fs::path dirPath, const std::string& matchString,
89 std::vector<fs::path>& foundPaths, unsigned int symlinkDepth)
James Feist6714a252018-09-10 15:26:18 -070090{
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -070091 if (!fs::exists(dirPath))
James Feist6714a252018-09-10 15:26:18 -070092 return false;
93
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -070094 std::regex search(matchString);
James Feist6714a252018-09-10 15:26:18 -070095 std::smatch match;
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -070096 for (auto& p : fs::recursive_directory_iterator(dirPath))
James Feist6714a252018-09-10 15:26:18 -070097 {
98 std::string path = p.path().string();
99 if (!is_directory(p))
100 {
101 if (std::regex_search(path, match, search))
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700102 foundPaths.emplace_back(p.path());
James Feist6714a252018-09-10 15:26:18 -0700103 }
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700104 else if (is_symlink(p) && symlinkDepth)
James Feist6714a252018-09-10 15:26:18 -0700105 {
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700106 findFiles(p.path(), matchString, foundPaths, symlinkDepth - 1);
James Feist6714a252018-09-10 15:26:18 -0700107 }
108 }
109 return true;
110}
111
James Feist71d31b22019-01-02 16:57:54 -0800112bool isPowerOn(void)
James Feist6714a252018-09-10 15:26:18 -0700113{
James Feist71d31b22019-01-02 16:57:54 -0800114 if (!powerMatch)
James Feist6714a252018-09-10 15:26:18 -0700115 {
James Feist71d31b22019-01-02 16:57:54 -0800116 throw std::runtime_error("Power Match Not Created");
James Feist6714a252018-09-10 15:26:18 -0700117 }
James Feist71d31b22019-01-02 16:57:54 -0800118 return powerStatusOn;
119}
120
121void setupPowerMatch(const std::shared_ptr<sdbusplus::asio::connection>& conn)
122{
James Feist6714a252018-09-10 15:26:18 -0700123
124 // create a match for powergood changes, first time do a method call to
James Feist71d31b22019-01-02 16:57:54 -0800125 // cache the correct value
James Feist6714a252018-09-10 15:26:18 -0700126 std::function<void(sdbusplus::message::message & message)> eventHandler =
James Feist3f0e8762018-11-27 11:30:42 -0800127 [](sdbusplus::message::message& message) {
James Feist6714a252018-09-10 15:26:18 -0700128 std::string objectName;
129 boost::container::flat_map<std::string,
130 sdbusplus::message::variant<int32_t>>
131 values;
132 message.read(objectName, values);
133 auto findPgood = values.find("pgood");
134 if (findPgood != values.end())
135 {
136 powerStatusOn = sdbusplus::message::variant_ns::get<int32_t>(
137 findPgood->second);
138 }
139 };
140
141 powerMatch = std::make_unique<sdbusplus::bus::match::match>(
142 static_cast<sdbusplus::bus::bus&>(*conn),
143 "type='signal',interface='org.freedesktop.DBus.Properties',path_"
144 "namespace='/xyz/openbmc_project/Chassis/Control/"
145 "power0',arg0='xyz.openbmc_project.Chassis.Control.Power'",
146 eventHandler);
147
148 conn->async_method_call(
James Feist3f0e8762018-11-27 11:30:42 -0800149 [](boost::system::error_code ec,
150 const sdbusplus::message::variant<int32_t>& pgood) {
James Feist6714a252018-09-10 15:26:18 -0700151 if (ec)
152 {
153 std::cerr << "Error getting initial power status\n";
154 return;
155 }
156 powerStatusOn = sdbusplus::message::variant_ns::get<int32_t>(pgood);
157 },
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700158 powerInterfaceName, powerObjectName, "org.freedesktop.DBus.Properties",
James Feistdc6c55f2018-10-31 12:53:20 -0700159 "Get", powerInterfaceName, "pgood");
James Feist3f0e8762018-11-27 11:30:42 -0800160}
James Feist87d713a2018-12-06 16:06:24 -0800161
162// replaces limits if MinReading and MaxReading are found.
163void findLimits(std::pair<double, double>& limits,
164 const SensorBaseConfiguration* data)
165{
166 if (!data)
167 {
168 return;
169 }
170 auto maxFind = data->second.find("MaxReading");
171 auto minFind = data->second.find("MinReading");
172
173 if (minFind != data->second.end())
174 {
175 limits.first = sdbusplus::message::variant_ns::visit(
176 VariantToDoubleVisitor(), minFind->second);
177 }
178 if (maxFind != data->second.end())
179 {
180 limits.second = sdbusplus::message::variant_ns::visit(
181 VariantToDoubleVisitor(), maxFind->second);
182 }
183}