blob: 67a8498b0b63bdf610d27f763f202acbf8e3a654 [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
Jim Wright19920832021-08-25 11:13:56 -050021#include <phosphor-logging/log.hpp>
22#include <sdbusplus/exception.hpp>
23#include <sdbusplus/sdbus.hpp>
24#include <sdbusplus/server.hpp>
25
Shawn McCarney768d2262024-07-09 15:02:59 -050026#include <format>
Jim Wright19920832021-08-25 11:13:56 -050027#include <string>
28#include <tuple>
29
30using namespace phosphor::logging;
31
32namespace phosphor::power::sequencer
33{
34
Patrick Williams7354ce62022-07-22 19:26:56 -050035PowerInterface::PowerInterface(sdbusplus::bus_t& bus, const char* path) :
Jim Wright213ffe92022-06-03 08:54:30 -050036 serverInterface(bus, path, POWER_IFACE, vtable, this)
Adriana Kobylak0c9a33d2021-09-13 18:05:09 +000037{}
Jim Wright19920832021-08-25 11:13:56 -050038
Patrick Williamsf5402192024-08-16 15:20:53 -040039int PowerInterface::callbackGetPgood(
40 sd_bus* /*bus*/, const char* /*path*/, const char* /*interface*/,
41 const char* /*property*/, sd_bus_message* msg, void* context,
42 sd_bus_error* error)
Jim Wright19920832021-08-25 11:13:56 -050043{
44 if (msg != nullptr && context != nullptr)
45 {
46 try
47 {
48 auto pwrObj = static_cast<PowerInterface*>(context);
49 int pgood = pwrObj->getPgood();
50 log<level::INFO>(
Shawn McCarney768d2262024-07-09 15:02:59 -050051 std::format("callbackGetPgood: {}", pgood).c_str());
Jim Wright19920832021-08-25 11:13:56 -050052
Patrick Williams7354ce62022-07-22 19:26:56 -050053 sdbusplus::message_t(msg).append(pgood);
Jim Wright19920832021-08-25 11:13:56 -050054 }
Patrick Williamsc1d4de52021-10-06 12:45:57 -050055 catch (const sdbusplus::exception_t& e)
Jim Wright19920832021-08-25 11:13:56 -050056 {
57 return sd_bus_error_set(error, e.name(), e.description());
58 }
59 }
60 else
61 {
62 // The message or context were null
63 log<level::ERR>("Unable to service get pgood property callback");
64 return -1;
65 }
66
67 return 1;
68}
69
Patrick Williamsf5402192024-08-16 15:20:53 -040070int PowerInterface::callbackGetPgoodTimeout(
71 sd_bus* /*bus*/, const char* /*path*/, const char* /*interface*/,
72 const char* /*property*/, sd_bus_message* msg, void* context,
73 sd_bus_error* error)
Jim Wright19920832021-08-25 11:13:56 -050074{
75 if (msg != nullptr && context != nullptr)
76 {
77 try
78 {
79 auto pwrObj = static_cast<PowerInterface*>(context);
80 int timeout = pwrObj->getPgoodTimeout();
81 log<level::INFO>(
Shawn McCarney768d2262024-07-09 15:02:59 -050082 std::format("callbackGetPgoodTimeout: {}", timeout).c_str());
Jim Wright19920832021-08-25 11:13:56 -050083
Patrick Williams7354ce62022-07-22 19:26:56 -050084 sdbusplus::message_t(msg).append(timeout);
Jim Wright19920832021-08-25 11:13:56 -050085 }
Patrick Williamsc1d4de52021-10-06 12:45:57 -050086 catch (const sdbusplus::exception_t& e)
Jim Wright19920832021-08-25 11:13:56 -050087 {
88 return sd_bus_error_set(error, e.name(), e.description());
89 }
90 }
91 else
92 {
93 // The message or context were null
94 log<level::ERR>(
95 "Unable to service get pgood timeout property callback");
96 return -1;
97 }
98
99 return 1;
100}
101
102int PowerInterface::callbackGetPowerState(sd_bus_message* msg, void* context,
103 sd_bus_error* error)
104{
105 if (msg != nullptr && context != nullptr)
106 {
107 try
108 {
109 auto pwrObj = static_cast<PowerInterface*>(context);
110 // Return the current power state of the GPIO, rather than the last
111 // requested power state change
112 int pgood = pwrObj->getPgood();
113 log<level::INFO>(
Shawn McCarney768d2262024-07-09 15:02:59 -0500114 std::format("callbackGetPowerState: {}", pgood).c_str());
Jim Wright19920832021-08-25 11:13:56 -0500115
Patrick Williams7354ce62022-07-22 19:26:56 -0500116 auto reply = sdbusplus::message_t(msg).new_method_return();
Jim Wright19920832021-08-25 11:13:56 -0500117 reply.append(pgood);
118 reply.method_return();
119 }
Patrick Williamsc1d4de52021-10-06 12:45:57 -0500120 catch (const sdbusplus::exception_t& e)
Jim Wright19920832021-08-25 11:13:56 -0500121 {
122 return sd_bus_error_set(error, e.name(), e.description());
123 }
124 }
125 else
126 {
127 // The message or context were null
128 log<level::ERR>("Unable to service getPowerState method callback");
129 return -1;
130 }
131
132 return 1;
133}
134
Patrick Williamsf5402192024-08-16 15:20:53 -0400135int PowerInterface::callbackSetPgoodTimeout(
136 sd_bus* /*bus*/, const char* /*path*/, const char* /*interface*/,
137 const char* /*property*/, sd_bus_message* msg, void* context,
138 sd_bus_error* error)
Jim Wright19920832021-08-25 11:13:56 -0500139{
140 if (msg != nullptr && context != nullptr)
141 {
142 try
143 {
Patrick Williams7354ce62022-07-22 19:26:56 -0500144 auto m = sdbusplus::message_t(msg);
Jim Wright19920832021-08-25 11:13:56 -0500145
146 int timeout{};
147 m.read(timeout);
Jim Wright19920832021-08-25 11:13:56 -0500148 log<level::INFO>(
Shawn McCarney768d2262024-07-09 15:02:59 -0500149 std::format("callbackSetPgoodTimeout: {}", timeout).c_str());
Jim Wrightccea2d22021-12-10 14:10:46 -0600150
151 auto pwrObj = static_cast<PowerInterface*>(context);
Jim Wright19920832021-08-25 11:13:56 -0500152 pwrObj->setPgoodTimeout(timeout);
153 }
Patrick Williamsc1d4de52021-10-06 12:45:57 -0500154 catch (const sdbusplus::exception_t& e)
Jim Wright19920832021-08-25 11:13:56 -0500155 {
156 return sd_bus_error_set(error, e.name(), e.description());
157 }
158 }
159 else
160 {
161 // The message or context were null
162 log<level::ERR>(
163 "Unable to service set pgood timeout property callback");
164 return -1;
165 }
166
167 return 1;
168}
169
Patrick Williamsf5402192024-08-16 15:20:53 -0400170int PowerInterface::callbackGetState(
171 sd_bus* /*bus*/, const char* /*path*/, const char* /*interface*/,
172 const char* /*property*/, sd_bus_message* msg, void* context,
173 sd_bus_error* error)
Jim Wright19920832021-08-25 11:13:56 -0500174{
175 if (msg != nullptr && context != nullptr)
176 {
177 try
178 {
179 auto pwrObj = static_cast<PowerInterface*>(context);
180 int state = pwrObj->getState();
181 log<level::INFO>(
Shawn McCarney768d2262024-07-09 15:02:59 -0500182 std::format("callbackGetState: {}", state).c_str());
Jim Wright19920832021-08-25 11:13:56 -0500183
Patrick Williams7354ce62022-07-22 19:26:56 -0500184 sdbusplus::message_t(msg).append(state);
Jim Wright19920832021-08-25 11:13:56 -0500185 }
Patrick Williamsc1d4de52021-10-06 12:45:57 -0500186 catch (const sdbusplus::exception_t& e)
Jim Wright19920832021-08-25 11:13:56 -0500187 {
188 return sd_bus_error_set(error, e.name(), e.description());
189 }
190 }
191 else
192 {
193 // The message or context were null
194 log<level::ERR>("Unable to service get state property callback");
195 return -1;
196 }
197
198 return 1;
199}
200
201int PowerInterface::callbackSetPowerState(sd_bus_message* msg, void* context,
202 sd_bus_error* error)
203{
204 if (msg != nullptr && context != nullptr)
205 {
206 try
207 {
Patrick Williams7354ce62022-07-22 19:26:56 -0500208 auto m = sdbusplus::message_t(msg);
Jim Wright19920832021-08-25 11:13:56 -0500209
210 int state{};
211 m.read(state);
212
213 if (state != 1 && state != 0)
214 {
215 return sd_bus_error_set(error,
216 "org.openbmc.ControlPower.Error.Failed",
217 "Invalid power state");
218 }
Jim Wright19920832021-08-25 11:13:56 -0500219 log<level::INFO>(
Shawn McCarney768d2262024-07-09 15:02:59 -0500220 std::format("callbackSetPowerState: {}", state).c_str());
Jim Wrightccea2d22021-12-10 14:10:46 -0600221
222 auto pwrObj = static_cast<PowerInterface*>(context);
Jim Wright19920832021-08-25 11:13:56 -0500223 pwrObj->setState(state);
224
225 m.new_method_return().method_return();
226 }
Patrick Williamsc1d4de52021-10-06 12:45:57 -0500227 catch (const sdbusplus::exception_t& e)
Jim Wright19920832021-08-25 11:13:56 -0500228 {
229 return sd_bus_error_set(error, e.name(), e.description());
230 }
231 }
232 else
233 {
234 // The message or context were null
235 log<level::ERR>("Unable to service setPowerState method callback");
236 return -1;
237 }
238
239 return 1;
240}
241
Patrick Williamsf5402192024-08-16 15:20:53 -0400242int PowerInterface::callbackSetPowerSupplyError(
243 sd_bus_message* msg, void* context, sd_bus_error* error)
Jim Wrightccea2d22021-12-10 14:10:46 -0600244{
245 if (msg != nullptr && context != nullptr)
246 {
247 try
248 {
Patrick Williams7354ce62022-07-22 19:26:56 -0500249 auto m = sdbusplus::message_t(msg);
Jim Wrightccea2d22021-12-10 14:10:46 -0600250
251 std::string psError{};
252 m.read(psError);
253 log<level::INFO>(
Shawn McCarney768d2262024-07-09 15:02:59 -0500254 std::format("callbackSetPowerSupplyError: {}", psError)
Jim Wrightccea2d22021-12-10 14:10:46 -0600255 .c_str());
256
257 auto pwrObj = static_cast<PowerInterface*>(context);
258 pwrObj->setPowerSupplyError(psError);
259
260 m.new_method_return().method_return();
261 }
262 catch (const sdbusplus::exception_t& e)
263 {
264 return sd_bus_error_set(error, e.name(), e.description());
265 }
266 }
267 else
268 {
269 // The message or context were null
270 log<level::ERR>(
271 "Unable to service setPowerSupplyError method callback");
272 return -1;
273 }
274
275 return 1;
276}
277
Jim Wright19920832021-08-25 11:13:56 -0500278void PowerInterface::emitPowerGoodSignal()
279{
280 log<level::INFO>("emitPowerGoodSignal");
Jim Wright213ffe92022-06-03 08:54:30 -0500281 serverInterface.new_signal("PowerGood").signal_send();
Jim Wright19920832021-08-25 11:13:56 -0500282}
283
284void PowerInterface::emitPowerLostSignal()
285{
286 log<level::INFO>("emitPowerLostSignal");
Jim Wright213ffe92022-06-03 08:54:30 -0500287 serverInterface.new_signal("PowerLost").signal_send();
Jim Wright19920832021-08-25 11:13:56 -0500288}
289
290void PowerInterface::emitPropertyChangedSignal(const char* property)
291{
292 log<level::INFO>(
Shawn McCarney768d2262024-07-09 15:02:59 -0500293 std::format("emitPropertyChangedSignal: {}", property).c_str());
Jim Wright213ffe92022-06-03 08:54:30 -0500294 serverInterface.property_changed(property);
Jim Wright19920832021-08-25 11:13:56 -0500295}
296
Jim Wright213ffe92022-06-03 08:54:30 -0500297const sdbusplus::vtable::vtable_t PowerInterface::vtable[] = {
Jim Wright19920832021-08-25 11:13:56 -0500298 sdbusplus::vtable::start(),
299 // Method setPowerState takes an int parameter and returns void
300 sdbusplus::vtable::method("setPowerState", "i", "", callbackSetPowerState),
301 // Method getPowerState takes no parameters and returns int
302 sdbusplus::vtable::method("getPowerState", "", "i", callbackGetPowerState),
303 // Signal PowerGood
304 sdbusplus::vtable::signal("PowerGood", ""),
305 // Signal PowerLost
306 sdbusplus::vtable::signal("PowerLost", ""),
307 // Property pgood is type int, read only, and uses the emits_change flag
308 sdbusplus::vtable::property("pgood", "i", callbackGetPgood,
309 sdbusplus::vtable::property_::emits_change),
310 // Property state is type int, read only, and uses the emits_change flag
311 sdbusplus::vtable::property("state", "i", callbackGetState,
312 sdbusplus::vtable::property_::emits_change),
313 // Property pgood_timeout is type int, read write, and uses the emits_change
314 // flag
315 sdbusplus::vtable::property("pgood_timeout", "i", callbackGetPgoodTimeout,
316 callbackSetPgoodTimeout,
317 sdbusplus::vtable::property_::emits_change),
Jim Wrightccea2d22021-12-10 14:10:46 -0600318 // Method setPowerSupplyError takes a string parameter and returns void
319 sdbusplus::vtable::method("setPowerSupplyError", "s", "",
320 callbackSetPowerSupplyError),
Jim Wright19920832021-08-25 11:13:56 -0500321 sdbusplus::vtable::end()};
322
323} // namespace phosphor::power::sequencer