blob: d266ee1ad64778ffcd58edd7eb2a44645e5d6f4e [file] [log] [blame]
Jim Wright19920832021-08-25 11:13:56 -05001/**
2 * Copyright © 2021 IBM 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 "power_interface.hpp"
18
19#include "types.hpp"
20
21#include <fmt/format.h>
22
23#include <phosphor-logging/log.hpp>
24#include <sdbusplus/exception.hpp>
25#include <sdbusplus/sdbus.hpp>
26#include <sdbusplus/server.hpp>
27
28#include <string>
29#include <tuple>
30
31using namespace phosphor::logging;
32
33namespace phosphor::power::sequencer
34{
35
36PowerInterface::PowerInterface(sdbusplus::bus::bus& bus, const char* path) :
37 _serverInterface(bus, path, POWER_IFACE, _vtable, this)
Adriana Kobylak0c9a33d2021-09-13 18:05:09 +000038{}
Jim Wright19920832021-08-25 11:13:56 -050039
40int PowerInterface::callbackGetPgood(sd_bus* /*bus*/, const char* /*path*/,
41 const char* /*interface*/,
42 const char* /*property*/,
43 sd_bus_message* msg, void* context,
44 sd_bus_error* error)
45{
46 if (msg != nullptr && context != nullptr)
47 {
48 try
49 {
50 auto pwrObj = static_cast<PowerInterface*>(context);
51 int pgood = pwrObj->getPgood();
52 log<level::INFO>(
53 fmt::format("callbackGetPgood: {}", pgood).c_str());
54
55 sdbusplus::message::message(msg).append(pgood);
56 }
Patrick Williamsc1d4de52021-10-06 12:45:57 -050057 catch (const sdbusplus::exception_t& e)
Jim Wright19920832021-08-25 11:13:56 -050058 {
59 return sd_bus_error_set(error, e.name(), e.description());
60 }
61 }
62 else
63 {
64 // The message or context were null
65 log<level::ERR>("Unable to service get pgood property callback");
66 return -1;
67 }
68
69 return 1;
70}
71
72int PowerInterface::callbackGetPgoodTimeout(sd_bus* /*bus*/,
73 const char* /*path*/,
74 const char* /*interface*/,
75 const char* /*property*/,
76 sd_bus_message* msg, void* context,
77 sd_bus_error* error)
78{
79 if (msg != nullptr && context != nullptr)
80 {
81 try
82 {
83 auto pwrObj = static_cast<PowerInterface*>(context);
84 int timeout = pwrObj->getPgoodTimeout();
85 log<level::INFO>(
86 fmt::format("callbackGetPgoodTimeout: {}", timeout).c_str());
87
88 sdbusplus::message::message(msg).append(timeout);
89 }
Patrick Williamsc1d4de52021-10-06 12:45:57 -050090 catch (const sdbusplus::exception_t& e)
Jim Wright19920832021-08-25 11:13:56 -050091 {
92 return sd_bus_error_set(error, e.name(), e.description());
93 }
94 }
95 else
96 {
97 // The message or context were null
98 log<level::ERR>(
99 "Unable to service get pgood timeout property callback");
100 return -1;
101 }
102
103 return 1;
104}
105
106int PowerInterface::callbackGetPowerState(sd_bus_message* msg, void* context,
107 sd_bus_error* error)
108{
109 if (msg != nullptr && context != nullptr)
110 {
111 try
112 {
113 auto pwrObj = static_cast<PowerInterface*>(context);
114 // Return the current power state of the GPIO, rather than the last
115 // requested power state change
116 int pgood = pwrObj->getPgood();
117 log<level::INFO>(
118 fmt::format("callbackGetPowerState: {}", pgood).c_str());
119
120 auto reply = sdbusplus::message::message(msg).new_method_return();
121 reply.append(pgood);
122 reply.method_return();
123 }
Patrick Williamsc1d4de52021-10-06 12:45:57 -0500124 catch (const sdbusplus::exception_t& e)
Jim Wright19920832021-08-25 11:13:56 -0500125 {
126 return sd_bus_error_set(error, e.name(), e.description());
127 }
128 }
129 else
130 {
131 // The message or context were null
132 log<level::ERR>("Unable to service getPowerState method callback");
133 return -1;
134 }
135
136 return 1;
137}
138
139int PowerInterface::callbackSetPgoodTimeout(sd_bus* /*bus*/,
140 const char* /*path*/,
141 const char* /*interface*/,
142 const char* /*property*/,
143 sd_bus_message* msg, void* context,
144 sd_bus_error* error)
145{
146 if (msg != nullptr && context != nullptr)
147 {
148 try
149 {
150 auto m = sdbusplus::message::message(msg);
151
152 int timeout{};
153 m.read(timeout);
Jim Wright19920832021-08-25 11:13:56 -0500154 log<level::INFO>(
155 fmt::format("callbackSetPgoodTimeout: {}", timeout).c_str());
Jim Wrightccea2d22021-12-10 14:10:46 -0600156
157 auto pwrObj = static_cast<PowerInterface*>(context);
Jim Wright19920832021-08-25 11:13:56 -0500158 pwrObj->setPgoodTimeout(timeout);
159 }
Patrick Williamsc1d4de52021-10-06 12:45:57 -0500160 catch (const sdbusplus::exception_t& e)
Jim Wright19920832021-08-25 11:13:56 -0500161 {
162 return sd_bus_error_set(error, e.name(), e.description());
163 }
164 }
165 else
166 {
167 // The message or context were null
168 log<level::ERR>(
169 "Unable to service set pgood timeout property callback");
170 return -1;
171 }
172
173 return 1;
174}
175
176int PowerInterface::callbackGetState(sd_bus* /*bus*/, const char* /*path*/,
177 const char* /*interface*/,
178 const char* /*property*/,
179 sd_bus_message* msg, void* context,
180 sd_bus_error* error)
181{
182 if (msg != nullptr && context != nullptr)
183 {
184 try
185 {
186 auto pwrObj = static_cast<PowerInterface*>(context);
187 int state = pwrObj->getState();
188 log<level::INFO>(
189 fmt::format("callbackGetState: {}", state).c_str());
190
191 sdbusplus::message::message(msg).append(state);
192 }
Patrick Williamsc1d4de52021-10-06 12:45:57 -0500193 catch (const sdbusplus::exception_t& e)
Jim Wright19920832021-08-25 11:13:56 -0500194 {
195 return sd_bus_error_set(error, e.name(), e.description());
196 }
197 }
198 else
199 {
200 // The message or context were null
201 log<level::ERR>("Unable to service get state property callback");
202 return -1;
203 }
204
205 return 1;
206}
207
208int PowerInterface::callbackSetPowerState(sd_bus_message* msg, void* context,
209 sd_bus_error* error)
210{
211 if (msg != nullptr && context != nullptr)
212 {
213 try
214 {
215 auto m = sdbusplus::message::message(msg);
216
217 int state{};
218 m.read(state);
219
220 if (state != 1 && state != 0)
221 {
222 return sd_bus_error_set(error,
223 "org.openbmc.ControlPower.Error.Failed",
224 "Invalid power state");
225 }
Jim Wright19920832021-08-25 11:13:56 -0500226 log<level::INFO>(
227 fmt::format("callbackSetPowerState: {}", state).c_str());
Jim Wrightccea2d22021-12-10 14:10:46 -0600228
229 auto pwrObj = static_cast<PowerInterface*>(context);
Jim Wright19920832021-08-25 11:13:56 -0500230 pwrObj->setState(state);
231
232 m.new_method_return().method_return();
233 }
Patrick Williamsc1d4de52021-10-06 12:45:57 -0500234 catch (const sdbusplus::exception_t& e)
Jim Wright19920832021-08-25 11:13:56 -0500235 {
236 return sd_bus_error_set(error, e.name(), e.description());
237 }
238 }
239 else
240 {
241 // The message or context were null
242 log<level::ERR>("Unable to service setPowerState method callback");
243 return -1;
244 }
245
246 return 1;
247}
248
Jim Wrightccea2d22021-12-10 14:10:46 -0600249int PowerInterface::callbackSetPowerSupplyError(sd_bus_message* msg,
250 void* context,
251 sd_bus_error* error)
252{
253 if (msg != nullptr && context != nullptr)
254 {
255 try
256 {
257 auto m = sdbusplus::message::message(msg);
258
259 std::string psError{};
260 m.read(psError);
261 log<level::INFO>(
262 fmt::format("callbackSetPowerSupplyError: {}", psError)
263 .c_str());
264
265 auto pwrObj = static_cast<PowerInterface*>(context);
266 pwrObj->setPowerSupplyError(psError);
267
268 m.new_method_return().method_return();
269 }
270 catch (const sdbusplus::exception_t& e)
271 {
272 return sd_bus_error_set(error, e.name(), e.description());
273 }
274 }
275 else
276 {
277 // The message or context were null
278 log<level::ERR>(
279 "Unable to service setPowerSupplyError method callback");
280 return -1;
281 }
282
283 return 1;
284}
285
Jim Wright19920832021-08-25 11:13:56 -0500286void PowerInterface::emitPowerGoodSignal()
287{
288 log<level::INFO>("emitPowerGoodSignal");
289 _serverInterface.new_signal("PowerGood").signal_send();
290}
291
292void PowerInterface::emitPowerLostSignal()
293{
294 log<level::INFO>("emitPowerLostSignal");
295 _serverInterface.new_signal("PowerLost").signal_send();
296}
297
298void PowerInterface::emitPropertyChangedSignal(const char* property)
299{
300 log<level::INFO>(
301 fmt::format("emitPropertyChangedSignal: {}", property).c_str());
302 _serverInterface.property_changed(property);
303}
304
305const sdbusplus::vtable::vtable_t PowerInterface::_vtable[] = {
306 sdbusplus::vtable::start(),
307 // Method setPowerState takes an int parameter and returns void
308 sdbusplus::vtable::method("setPowerState", "i", "", callbackSetPowerState),
309 // Method getPowerState takes no parameters and returns int
310 sdbusplus::vtable::method("getPowerState", "", "i", callbackGetPowerState),
311 // Signal PowerGood
312 sdbusplus::vtable::signal("PowerGood", ""),
313 // Signal PowerLost
314 sdbusplus::vtable::signal("PowerLost", ""),
315 // Property pgood is type int, read only, and uses the emits_change flag
316 sdbusplus::vtable::property("pgood", "i", callbackGetPgood,
317 sdbusplus::vtable::property_::emits_change),
318 // Property state is type int, read only, and uses the emits_change flag
319 sdbusplus::vtable::property("state", "i", callbackGetState,
320 sdbusplus::vtable::property_::emits_change),
321 // Property pgood_timeout is type int, read write, and uses the emits_change
322 // flag
323 sdbusplus::vtable::property("pgood_timeout", "i", callbackGetPgoodTimeout,
324 callbackSetPgoodTimeout,
325 sdbusplus::vtable::property_::emits_change),
Jim Wrightccea2d22021-12-10 14:10:46 -0600326 // Method setPowerSupplyError takes a string parameter and returns void
327 sdbusplus::vtable::method("setPowerSupplyError", "s", "",
328 callbackSetPowerSupplyError),
Jim Wright19920832021-08-25 11:13:56 -0500329 sdbusplus::vtable::end()};
330
331} // namespace phosphor::power::sequencer