blob: 50f5911ad69a18801cc37497008a58283ffaa06a [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);
154
155 auto pwrObj = static_cast<PowerInterface*>(context);
156 log<level::INFO>(
157 fmt::format("callbackSetPgoodTimeout: {}", timeout).c_str());
158 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 }
226
227 auto pwrObj = static_cast<PowerInterface*>(context);
228 log<level::INFO>(
229 fmt::format("callbackSetPowerState: {}", state).c_str());
230 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
249void PowerInterface::emitPowerGoodSignal()
250{
251 log<level::INFO>("emitPowerGoodSignal");
252 _serverInterface.new_signal("PowerGood").signal_send();
253}
254
255void PowerInterface::emitPowerLostSignal()
256{
257 log<level::INFO>("emitPowerLostSignal");
258 _serverInterface.new_signal("PowerLost").signal_send();
259}
260
261void PowerInterface::emitPropertyChangedSignal(const char* property)
262{
263 log<level::INFO>(
264 fmt::format("emitPropertyChangedSignal: {}", property).c_str());
265 _serverInterface.property_changed(property);
266}
267
268const sdbusplus::vtable::vtable_t PowerInterface::_vtable[] = {
269 sdbusplus::vtable::start(),
270 // Method setPowerState takes an int parameter and returns void
271 sdbusplus::vtable::method("setPowerState", "i", "", callbackSetPowerState),
272 // Method getPowerState takes no parameters and returns int
273 sdbusplus::vtable::method("getPowerState", "", "i", callbackGetPowerState),
274 // Signal PowerGood
275 sdbusplus::vtable::signal("PowerGood", ""),
276 // Signal PowerLost
277 sdbusplus::vtable::signal("PowerLost", ""),
278 // Property pgood is type int, read only, and uses the emits_change flag
279 sdbusplus::vtable::property("pgood", "i", callbackGetPgood,
280 sdbusplus::vtable::property_::emits_change),
281 // Property state is type int, read only, and uses the emits_change flag
282 sdbusplus::vtable::property("state", "i", callbackGetState,
283 sdbusplus::vtable::property_::emits_change),
284 // Property pgood_timeout is type int, read write, and uses the emits_change
285 // flag
286 sdbusplus::vtable::property("pgood_timeout", "i", callbackGetPgoodTimeout,
287 callbackSetPgoodTimeout,
288 sdbusplus::vtable::property_::emits_change),
289 sdbusplus::vtable::end()};
290
291} // namespace phosphor::power::sequencer