blob: 768f708dfe8258a8d7ec42ab801a06adc23b70ec [file] [log] [blame]
James Feist139cb572018-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>
19#include <experimental/filesystem>
20#include <fstream>
21#include <regex>
22#include <sdbusplus/asio/connection.hpp>
23#include <sdbusplus/bus/match.hpp>
24
25namespace fs = std::experimental::filesystem;
Jae Hyun Yoof78ec412018-10-25 10:42:39 -070026const static constexpr char* powerInterfaceName =
James Feist139cb572018-09-10 15:26:18 -070027 "xyz.openbmc_project.Chassis.Control.Power";
Jae Hyun Yoof78ec412018-10-25 10:42:39 -070028const static constexpr char* powerObjectName =
James Feist139cb572018-09-10 15:26:18 -070029 "/xyz/openbmc_project/Chassis/Control/Power0";
30
31bool getSensorConfiguration(
32 const std::string& type,
33 const std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
34 ManagedObjectType& resp, bool useCache)
35{
36 static ManagedObjectType managedObj;
37
38 if (!useCache)
39 {
40 managedObj.clear();
41 sdbusplus::message::message getManagedObjects =
42 dbusConnection->new_method_call(
Jae Hyun Yoof78ec412018-10-25 10:42:39 -070043 entityManagerName, "/", "org.freedesktop.DBus.ObjectManager",
James Feist139cb572018-09-10 15:26:18 -070044 "GetManagedObjects");
45 bool err = false;
46 try
47 {
48 sdbusplus::message::message reply =
49 dbusConnection->call(getManagedObjects);
Yoo, Jae Hyun9fbe2b22018-10-15 14:05:37 -070050 reply.read(managedObj);
James Feist139cb572018-09-10 15:26:18 -070051 }
52 catch (const sdbusplus::exception::exception&)
53 {
54 err = true;
55 }
56
57 if (err)
58 {
59 std::cerr << "Error communicating to entity manager\n";
60 return false;
61 }
62 }
63 for (const auto& pathPair : managedObj)
64 {
65 std::vector<boost::container::flat_map<std::string, BasicVariantType>>
66 sensorData;
67 bool correctType = false;
68 for (const auto& entry : pathPair.second)
69 {
70 if (boost::starts_with(entry.first, type))
71 {
72 correctType = true;
73 break;
74 }
75 }
76 if (correctType)
77 {
78 resp.emplace(pathPair);
79 }
80 }
81 return true;
82}
83
Jae Hyun Yoof78ec412018-10-25 10:42:39 -070084bool findFiles(const fs::path dirPath, const std::string& matchString,
85 std::vector<fs::path>& foundPaths, unsigned int symlinkDepth)
James Feist139cb572018-09-10 15:26:18 -070086{
Jae Hyun Yoof78ec412018-10-25 10:42:39 -070087 if (!fs::exists(dirPath))
James Feist139cb572018-09-10 15:26:18 -070088 return false;
89
Jae Hyun Yoof78ec412018-10-25 10:42:39 -070090 std::regex search(matchString);
James Feist139cb572018-09-10 15:26:18 -070091 std::smatch match;
Jae Hyun Yoof78ec412018-10-25 10:42:39 -070092 for (auto& p : fs::recursive_directory_iterator(dirPath))
James Feist139cb572018-09-10 15:26:18 -070093 {
94 std::string path = p.path().string();
95 if (!is_directory(p))
96 {
97 if (std::regex_search(path, match, search))
Jae Hyun Yoof78ec412018-10-25 10:42:39 -070098 foundPaths.emplace_back(p.path());
James Feist139cb572018-09-10 15:26:18 -070099 }
Jae Hyun Yoof78ec412018-10-25 10:42:39 -0700100 else if (is_symlink(p) && symlinkDepth)
James Feist139cb572018-09-10 15:26:18 -0700101 {
Jae Hyun Yoof78ec412018-10-25 10:42:39 -0700102 findFiles(p.path(), matchString, foundPaths, symlinkDepth - 1);
James Feist139cb572018-09-10 15:26:18 -0700103 }
104 }
105 return true;
106}
107
108// initially returns false, then sets up matches and returns status
109// should be called once first to initialize
110bool isPowerOn(const std::shared_ptr<sdbusplus::asio::connection>& conn)
111{
112 static std::unique_ptr<sdbusplus::bus::match::match> powerMatch = nullptr;
113 static bool powerStatusOn = false;
114
115 if (powerMatch != nullptr)
116 {
117 return powerStatusOn;
118 }
119
120 // create a match for powergood changes, first time do a method call to
121 // return the correct value
122 std::function<void(sdbusplus::message::message & message)> eventHandler =
123 [&powerStatusOn](sdbusplus::message::message& message) {
124 std::string objectName;
125 boost::container::flat_map<std::string,
126 sdbusplus::message::variant<int32_t>>
127 values;
128 message.read(objectName, values);
129 auto findPgood = values.find("pgood");
130 if (findPgood != values.end())
131 {
132 powerStatusOn = sdbusplus::message::variant_ns::get<int32_t>(
133 findPgood->second);
134 }
135 };
136
137 powerMatch = std::make_unique<sdbusplus::bus::match::match>(
138 static_cast<sdbusplus::bus::bus&>(*conn),
139 "type='signal',interface='org.freedesktop.DBus.Properties',path_"
140 "namespace='/xyz/openbmc_project/Chassis/Control/"
141 "power0',arg0='xyz.openbmc_project.Chassis.Control.Power'",
142 eventHandler);
143
144 conn->async_method_call(
145 [&powerStatusOn](boost::system::error_code ec,
146 const sdbusplus::message::variant<int32_t>& pgood) {
147 if (ec)
148 {
149 std::cerr << "Error getting initial power status\n";
150 return;
151 }
152 powerStatusOn = sdbusplus::message::variant_ns::get<int32_t>(pgood);
153 },
Jae Hyun Yoof78ec412018-10-25 10:42:39 -0700154 powerInterfaceName, powerObjectName, "org.freedesktop.DBus.Properties",
155 "Get", "pgood");
James Feist139cb572018-09-10 15:26:18 -0700156
157 return powerStatusOn;
158}