blob: ec85e416c69993eab5a1af622caab5e1d065b3ff [file] [log] [blame]
NodeMan9727d1e142022-07-27 15:10:07 -05001#include "config.h"
2
Carol Wangdc059392020-03-13 17:39:17 +08003#include "utils.hpp"
4
NodeMan9727d1e142022-07-27 15:10:07 -05005#include <fmt/format.h>
6#include <fmt/printf.h>
Andrew Geisslerf8ae6a02022-01-21 17:00:20 -06007#include <gpiod.h>
8
Andrew Geissler8ffdb262021-09-20 15:25:19 -05009#include <phosphor-logging/lg2.hpp>
Carol Wangdc059392020-03-13 17:39:17 +080010
NodeMan9727d1e142022-07-27 15:10:07 -050011#include <filesystem>
12
Carol Wangdc059392020-03-13 17:39:17 +080013namespace phosphor
14{
15namespace state
16{
17namespace manager
18{
19namespace utils
20{
21
Andrew Geissler8ffdb262021-09-20 15:25:19 -050022PHOSPHOR_LOG2_USING;
Carol Wangdc059392020-03-13 17:39:17 +080023
Andrew Geissler928bbf12023-02-14 13:30:14 -060024constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
25constexpr auto SYSTEMD_OBJ_PATH = "/org/freedesktop/systemd1";
26constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
27
Carol Wangdc059392020-03-13 17:39:17 +080028constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
29constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
30constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
31constexpr auto PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties";
32
Andrew Geissler928bbf12023-02-14 13:30:14 -060033void subscribeToSystemdSignals(sdbusplus::bus::bus& bus)
34{
35 auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_OBJ_PATH,
36 SYSTEMD_INTERFACE, "Subscribe");
37
38 try
39 {
40 bus.call(method);
41 }
42 catch (const sdbusplus::exception_t& e)
43 {
44 error("Failed to subscribe to systemd signals: {ERROR}", "ERROR", e);
45 throw std::runtime_error("Unable to subscribe to systemd signals");
46 }
47 return;
48}
49
50std::string getService(sdbusplus::bus::bus& bus, std::string path,
Carol Wangdc059392020-03-13 17:39:17 +080051 std::string interface)
52{
53 auto mapper = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH,
54 MAPPER_INTERFACE, "GetObject");
55
56 mapper.append(path, std::vector<std::string>({interface}));
57
58 std::vector<std::pair<std::string, std::vector<std::string>>>
59 mapperResponse;
60
61 try
62 {
63 auto mapperResponseMsg = bus.call(mapper);
64
65 mapperResponseMsg.read(mapperResponse);
66 if (mapperResponse.empty())
67 {
Andrew Geisslerad65b2d2021-09-21 12:53:29 -050068 error(
69 "Error no matching service with path {PATH} and interface {INTERFACE}",
70 "PATH", path, "INTERFACE", interface);
Carol Wangdc059392020-03-13 17:39:17 +080071 throw std::runtime_error("Error no matching service");
72 }
73 }
Patrick Williamsf053e6f2022-07-22 19:26:54 -050074 catch (const sdbusplus::exception_t& e)
Carol Wangdc059392020-03-13 17:39:17 +080075 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -050076 error("Error in mapper call with path {PATH}, interface "
77 "{INTERFACE}, and exception {ERROR}",
78 "PATH", path, "INTERFACE", interface, "ERROR", e);
Carol Wangdc059392020-03-13 17:39:17 +080079 throw;
80 }
81
82 return mapperResponse.begin()->first;
83}
84
Patrick Williamsf053e6f2022-07-22 19:26:54 -050085std::string getProperty(sdbusplus::bus_t& bus, const std::string& path,
Andrew Geissler49e67132022-01-26 14:27:52 -060086 const std::string& interface,
87 const std::string& propertyName)
88{
89 std::variant<std::string> property;
90 std::string service = getService(bus, path, interface);
91
92 auto method = bus.new_method_call(service.c_str(), path.c_str(),
93 PROPERTY_INTERFACE, "Get");
94
95 method.append(interface, propertyName);
96
97 try
98 {
99 auto reply = bus.call(method);
100 reply.read(property);
101 }
Patrick Williamsf053e6f2022-07-22 19:26:54 -0500102 catch (const sdbusplus::exception_t& e)
Andrew Geissler49e67132022-01-26 14:27:52 -0600103 {
104 error("Error in property Get, error {ERROR}, property {PROPERTY}",
105 "ERROR", e, "PROPERTY", propertyName);
106 throw;
107 }
108
109 if (std::get<std::string>(property).empty())
110 {
111 error("Error reading property response for {PROPERTY}", "PROPERTY",
112 propertyName);
113 throw std::runtime_error("Error reading property response");
114 }
115
116 return std::get<std::string>(property);
117}
118
Patrick Williamsf053e6f2022-07-22 19:26:54 -0500119void setProperty(sdbusplus::bus_t& bus, const std::string& path,
Carol Wangdc059392020-03-13 17:39:17 +0800120 const std::string& interface, const std::string& property,
121 const std::string& value)
122{
Patrick Williams2975e262020-05-13 18:01:09 -0500123 std::variant<std::string> variantValue = value;
Carol Wangdc059392020-03-13 17:39:17 +0800124 std::string service = getService(bus, path, interface);
125
126 auto method = bus.new_method_call(service.c_str(), path.c_str(),
127 PROPERTY_INTERFACE, "Set");
128
129 method.append(interface, property, variantValue);
130 bus.call_noreply(method);
131
132 return;
133}
134
Andrew Geisslerf8ae6a02022-01-21 17:00:20 -0600135int getGpioValue(const std::string& gpioName)
136{
Andrew Geisslerf8ae6a02022-01-21 17:00:20 -0600137 int gpioval = -1;
138 gpiod_line* line = gpiod_line_find(gpioName.c_str());
139
140 if (nullptr != line)
141 {
142 // take ownership of gpio
143 if (0 != gpiod_line_request_input(line, "state-manager"))
144 {
145 error("Failed request for {GPIO_NAME} GPIO", "GPIO_NAME", gpioName);
146 }
147 else
148 {
149 // get gpio value
150 gpioval = gpiod_line_get_value(line);
151
152 // release ownership of gpio
153 gpiod_line_close_chip(line);
154 }
155 }
156 return gpioval;
157}
158
Andrew Geissler9d4d0c92022-01-26 13:18:12 -0600159void createError(
Patrick Williamsf053e6f2022-07-22 19:26:54 -0500160 sdbusplus::bus_t& bus, const std::string& errorMsg,
Andrew Geisslerd49f51e2022-03-07 14:57:07 -0600161 sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level errLevel,
162 std::map<std::string, std::string> additionalData)
Andrew Geissler9d4d0c92022-01-26 13:18:12 -0600163{
Andrew Geissler9d4d0c92022-01-26 13:18:12 -0600164 try
165 {
Andrew Geisslerd49f51e2022-03-07 14:57:07 -0600166 // Always add the _PID on for some extra logging debug
Andrew Geissler9d4d0c92022-01-26 13:18:12 -0600167 additionalData.emplace("_PID", std::to_string(getpid()));
168
169 auto method = bus.new_method_call(
170 "xyz.openbmc_project.Logging", "/xyz/openbmc_project/logging",
171 "xyz.openbmc_project.Logging.Create", "Create");
172
173 method.append(errorMsg, errLevel, additionalData);
174 auto resp = bus.call(method);
175 }
Patrick Williamsf053e6f2022-07-22 19:26:54 -0500176 catch (const sdbusplus::exception_t& e)
Andrew Geissler9d4d0c92022-01-26 13:18:12 -0600177 {
178 error("sdbusplus D-Bus call exception, error {ERROR} trying to create "
179 "an error with {ERROR_MSG}",
180 "ERROR", e, "ERROR_MSG", errorMsg);
181
182 throw std::runtime_error(
183 "Error in invoking D-Bus logging create interface");
184 }
185 catch (const std::exception& e)
186 {
187 error("D-bus call exception: {ERROR}", "ERROR", e);
188 throw e;
189 }
190}
191
Patrick Williamsf053e6f2022-07-22 19:26:54 -0500192void createBmcDump(sdbusplus::bus_t& bus)
Andrew Geissler55e96ac2022-04-19 11:44:53 -0400193{
194 auto method = bus.new_method_call(
195 "xyz.openbmc_project.Dump.Manager", "/xyz/openbmc_project/dump/bmc",
196 "xyz.openbmc_project.Dump.Create", "CreateDump");
197 method.append(
198 std::vector<
199 std::pair<std::string, std::variant<std::string, uint64_t>>>());
200 try
201 {
202 bus.call_noreply(method);
203 }
Patrick Williamsf053e6f2022-07-22 19:26:54 -0500204 catch (const sdbusplus::exception_t& e)
Andrew Geissler55e96ac2022-04-19 11:44:53 -0400205 {
206 error("Failed to create BMC dump, exception:{ERROR}", "ERROR", e);
207 // just continue, this is error path anyway so we're just collecting
208 // what we can
209 }
210}
211
NodeMan9727d1e142022-07-27 15:10:07 -0500212bool checkACLoss(size_t& chassisId)
213{
214 std::string chassisLostPowerFileFmt =
215 fmt::sprintf(CHASSIS_LOST_POWER_FILE, chassisId);
216
217 std::filesystem::path chassisPowerLossFile{chassisLostPowerFileFmt};
218 if (std::filesystem::exists(chassisPowerLossFile))
219 {
220 return true;
221 }
222
223 return false;
224}
225
Carol Wangdc059392020-03-13 17:39:17 +0800226} // namespace utils
227} // namespace manager
228} // namespace state
229} // namespace phosphor