blob: 77b20eb3aedb6f7fb75df3cb90df96f583009f2e [file] [log] [blame]
Carol Wangdc059392020-03-13 17:39:17 +08001#include "utils.hpp"
2
Andrew Geisslerf8ae6a02022-01-21 17:00:20 -06003#include <gpiod.h>
4
Andrew Geissler8ffdb262021-09-20 15:25:19 -05005#include <phosphor-logging/lg2.hpp>
Carol Wangdc059392020-03-13 17:39:17 +08006
7namespace phosphor
8{
9namespace state
10{
11namespace manager
12{
13namespace utils
14{
15
Andrew Geissler8ffdb262021-09-20 15:25:19 -050016PHOSPHOR_LOG2_USING;
Carol Wangdc059392020-03-13 17:39:17 +080017
18constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
19constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
20constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
21constexpr auto PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties";
22
23std::string getService(sdbusplus::bus::bus& bus, std::string path,
24 std::string interface)
25{
26 auto mapper = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH,
27 MAPPER_INTERFACE, "GetObject");
28
29 mapper.append(path, std::vector<std::string>({interface}));
30
31 std::vector<std::pair<std::string, std::vector<std::string>>>
32 mapperResponse;
33
34 try
35 {
36 auto mapperResponseMsg = bus.call(mapper);
37
38 mapperResponseMsg.read(mapperResponse);
39 if (mapperResponse.empty())
40 {
Andrew Geisslerad65b2d2021-09-21 12:53:29 -050041 error(
42 "Error no matching service with path {PATH} and interface {INTERFACE}",
43 "PATH", path, "INTERFACE", interface);
Carol Wangdc059392020-03-13 17:39:17 +080044 throw std::runtime_error("Error no matching service");
45 }
46 }
Patrick Williams0a675212021-09-02 09:49:43 -050047 catch (const sdbusplus::exception::exception& e)
Carol Wangdc059392020-03-13 17:39:17 +080048 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -050049 error("Error in mapper call with path {PATH}, interface "
50 "{INTERFACE}, and exception {ERROR}",
51 "PATH", path, "INTERFACE", interface, "ERROR", e);
Carol Wangdc059392020-03-13 17:39:17 +080052 throw;
53 }
54
55 return mapperResponse.begin()->first;
56}
57
Andrew Geissler49e67132022-01-26 14:27:52 -060058std::string getProperty(sdbusplus::bus::bus& bus, const std::string& path,
59 const std::string& interface,
60 const std::string& propertyName)
61{
62 std::variant<std::string> property;
63 std::string service = getService(bus, path, interface);
64
65 auto method = bus.new_method_call(service.c_str(), path.c_str(),
66 PROPERTY_INTERFACE, "Get");
67
68 method.append(interface, propertyName);
69
70 try
71 {
72 auto reply = bus.call(method);
73 reply.read(property);
74 }
75 catch (const sdbusplus::exception::exception& e)
76 {
77 error("Error in property Get, error {ERROR}, property {PROPERTY}",
78 "ERROR", e, "PROPERTY", propertyName);
79 throw;
80 }
81
82 if (std::get<std::string>(property).empty())
83 {
84 error("Error reading property response for {PROPERTY}", "PROPERTY",
85 propertyName);
86 throw std::runtime_error("Error reading property response");
87 }
88
89 return std::get<std::string>(property);
90}
91
Carol Wangdc059392020-03-13 17:39:17 +080092void setProperty(sdbusplus::bus::bus& bus, const std::string& path,
93 const std::string& interface, const std::string& property,
94 const std::string& value)
95{
Patrick Williams2975e262020-05-13 18:01:09 -050096 std::variant<std::string> variantValue = value;
Carol Wangdc059392020-03-13 17:39:17 +080097 std::string service = getService(bus, path, interface);
98
99 auto method = bus.new_method_call(service.c_str(), path.c_str(),
100 PROPERTY_INTERFACE, "Set");
101
102 method.append(interface, property, variantValue);
103 bus.call_noreply(method);
104
105 return;
106}
107
Andrew Geisslerf8ae6a02022-01-21 17:00:20 -0600108int getGpioValue(const std::string& gpioName)
109{
Andrew Geisslerf8ae6a02022-01-21 17:00:20 -0600110 int gpioval = -1;
111 gpiod_line* line = gpiod_line_find(gpioName.c_str());
112
113 if (nullptr != line)
114 {
115 // take ownership of gpio
116 if (0 != gpiod_line_request_input(line, "state-manager"))
117 {
118 error("Failed request for {GPIO_NAME} GPIO", "GPIO_NAME", gpioName);
119 }
120 else
121 {
122 // get gpio value
123 gpioval = gpiod_line_get_value(line);
124
125 // release ownership of gpio
126 gpiod_line_close_chip(line);
127 }
128 }
129 return gpioval;
130}
131
Andrew Geissler9d4d0c92022-01-26 13:18:12 -0600132void createError(
133 sdbusplus::bus::bus& bus, const std::string& errorMsg,
Andrew Geisslerd49f51e2022-03-07 14:57:07 -0600134 sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level errLevel,
135 std::map<std::string, std::string> additionalData)
Andrew Geissler9d4d0c92022-01-26 13:18:12 -0600136{
Andrew Geissler9d4d0c92022-01-26 13:18:12 -0600137 try
138 {
Andrew Geisslerd49f51e2022-03-07 14:57:07 -0600139 // Always add the _PID on for some extra logging debug
Andrew Geissler9d4d0c92022-01-26 13:18:12 -0600140 additionalData.emplace("_PID", std::to_string(getpid()));
141
142 auto method = bus.new_method_call(
143 "xyz.openbmc_project.Logging", "/xyz/openbmc_project/logging",
144 "xyz.openbmc_project.Logging.Create", "Create");
145
146 method.append(errorMsg, errLevel, additionalData);
147 auto resp = bus.call(method);
148 }
149 catch (const sdbusplus::exception::exception& e)
150 {
151 error("sdbusplus D-Bus call exception, error {ERROR} trying to create "
152 "an error with {ERROR_MSG}",
153 "ERROR", e, "ERROR_MSG", errorMsg);
154
155 throw std::runtime_error(
156 "Error in invoking D-Bus logging create interface");
157 }
158 catch (const std::exception& e)
159 {
160 error("D-bus call exception: {ERROR}", "ERROR", e);
161 throw e;
162 }
163}
164
Andrew Geissler55e96ac2022-04-19 11:44:53 -0400165void createBmcDump(sdbusplus::bus::bus& bus)
166{
167 auto method = bus.new_method_call(
168 "xyz.openbmc_project.Dump.Manager", "/xyz/openbmc_project/dump/bmc",
169 "xyz.openbmc_project.Dump.Create", "CreateDump");
170 method.append(
171 std::vector<
172 std::pair<std::string, std::variant<std::string, uint64_t>>>());
173 try
174 {
175 bus.call_noreply(method);
176 }
177 catch (const sdbusplus::exception::exception& e)
178 {
179 error("Failed to create BMC dump, exception:{ERROR}", "ERROR", e);
180 // just continue, this is error path anyway so we're just collecting
181 // what we can
182 }
183}
184
Carol Wangdc059392020-03-13 17:39:17 +0800185} // namespace utils
186} // namespace manager
187} // namespace state
188} // namespace phosphor