blob: 6ce3f18528df098aa75163d9d2a930d234f9ac92 [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;
26const static constexpr char* POWER_INTERFACE_NAME =
27 "xyz.openbmc_project.Chassis.Control.Power";
28const static constexpr char* POWER_OBJECT_NAME =
29 "/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(
43 ENTITY_MANAGER_NAME, "/", "org.freedesktop.DBus.ObjectManager",
44 "GetManagedObjects");
45 bool err = false;
46 try
47 {
48 sdbusplus::message::message reply =
49 dbusConnection->call(getManagedObjects);
50 err = reply.is_method_error();
51 if (!err)
52 {
53 reply.read(managedObj);
54 }
55 }
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
88bool find_files(const fs::path dir_path, const std::string& match_string,
89 std::vector<fs::path>& found_paths, unsigned int symlink_depth)
90{
91 if (!fs::exists(dir_path))
92 return false;
93
94 fs::directory_iterator end_itr;
95 std::regex search(match_string);
96 std::smatch match;
97 for (auto& p : fs::recursive_directory_iterator(dir_path))
98 {
99 std::string path = p.path().string();
100 if (!is_directory(p))
101 {
102 if (std::regex_search(path, match, search))
103 found_paths.emplace_back(p.path());
104 }
105 // since we're using a recursive iterator, these should only be symlink
106 // dirs
107 else if (symlink_depth)
108 {
109 find_files(p.path(), match_string, found_paths, symlink_depth - 1);
110 }
111 }
112 return true;
113}
114
115// initially returns false, then sets up matches and returns status
116// should be called once first to initialize
117bool isPowerOn(const std::shared_ptr<sdbusplus::asio::connection>& conn)
118{
119 static std::unique_ptr<sdbusplus::bus::match::match> powerMatch = nullptr;
120 static bool powerStatusOn = false;
121
122 if (powerMatch != nullptr)
123 {
124 return powerStatusOn;
125 }
126
127 // create a match for powergood changes, first time do a method call to
128 // return the correct value
129 std::function<void(sdbusplus::message::message & message)> eventHandler =
130 [&powerStatusOn](sdbusplus::message::message& message) {
131 std::string objectName;
132 boost::container::flat_map<std::string,
133 sdbusplus::message::variant<int32_t>>
134 values;
135 message.read(objectName, values);
136 auto findPgood = values.find("pgood");
137 if (findPgood != values.end())
138 {
139 powerStatusOn = sdbusplus::message::variant_ns::get<int32_t>(
140 findPgood->second);
141 }
142 };
143
144 powerMatch = std::make_unique<sdbusplus::bus::match::match>(
145 static_cast<sdbusplus::bus::bus&>(*conn),
146 "type='signal',interface='org.freedesktop.DBus.Properties',path_"
147 "namespace='/xyz/openbmc_project/Chassis/Control/"
148 "power0',arg0='xyz.openbmc_project.Chassis.Control.Power'",
149 eventHandler);
150
151 conn->async_method_call(
152 [&powerStatusOn](boost::system::error_code ec,
153 const sdbusplus::message::variant<int32_t>& pgood) {
154 if (ec)
155 {
156 std::cerr << "Error getting initial power status\n";
157 return;
158 }
159 powerStatusOn = sdbusplus::message::variant_ns::get<int32_t>(pgood);
160 },
161 POWER_INTERFACE_NAME, POWER_OBJECT_NAME,
162 "org.freedesktop.DBus.Properties", "Get", "pgood");
163
164 return powerStatusOn;
165}