11992083aSJim Wright /**
21992083aSJim Wright * Copyright © 2021 IBM Corporation
31992083aSJim Wright *
41992083aSJim Wright * Licensed under the Apache License, Version 2.0 (the "License");
51992083aSJim Wright * you may not use this file except in compliance with the License.
61992083aSJim Wright * You may obtain a copy of the License at
71992083aSJim Wright *
81992083aSJim Wright * http://www.apache.org/licenses/LICENSE-2.0
91992083aSJim Wright *
101992083aSJim Wright * Unless required by applicable law or agreed to in writing, software
111992083aSJim Wright * distributed under the License is distributed on an "AS IS" BASIS,
121992083aSJim Wright * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131992083aSJim Wright * See the License for the specific language governing permissions and
141992083aSJim Wright * limitations under the License.
151992083aSJim Wright */
161992083aSJim Wright
171992083aSJim Wright #include "power_interface.hpp"
181992083aSJim Wright
191992083aSJim Wright #include "types.hpp"
201992083aSJim Wright
21*31ae6ee8SAnwaar Hadi #include <phosphor-logging/lg2.hpp>
221992083aSJim Wright #include <sdbusplus/exception.hpp>
231992083aSJim Wright #include <sdbusplus/sdbus.hpp>
241992083aSJim Wright #include <sdbusplus/server.hpp>
251992083aSJim Wright
261992083aSJim Wright #include <string>
271992083aSJim Wright #include <tuple>
281992083aSJim Wright
291992083aSJim Wright namespace phosphor::power::sequencer
301992083aSJim Wright {
311992083aSJim Wright
PowerInterface(sdbusplus::bus_t & bus,const char * path)327354ce62SPatrick Williams PowerInterface::PowerInterface(sdbusplus::bus_t& bus, const char* path) :
33213ffe99SJim Wright serverInterface(bus, path, POWER_IFACE, vtable, this)
340c9a33d6SAdriana Kobylak {}
351992083aSJim Wright
callbackGetPgood(sd_bus *,const char *,const char *,const char *,sd_bus_message * msg,void * context,sd_bus_error * error)36f5402197SPatrick Williams int PowerInterface::callbackGetPgood(
37f5402197SPatrick Williams sd_bus* /*bus*/, const char* /*path*/, const char* /*interface*/,
38f5402197SPatrick Williams const char* /*property*/, sd_bus_message* msg, void* context,
391992083aSJim Wright sd_bus_error* error)
401992083aSJim Wright {
411992083aSJim Wright if (msg != nullptr && context != nullptr)
421992083aSJim Wright {
431992083aSJim Wright try
441992083aSJim Wright {
451992083aSJim Wright auto pwrObj = static_cast<PowerInterface*>(context);
461992083aSJim Wright int pgood = pwrObj->getPgood();
47*31ae6ee8SAnwaar Hadi lg2::debug("callbackGetPgood: {PGOOD}", "PGOOD", pgood);
481992083aSJim Wright
497354ce62SPatrick Williams sdbusplus::message_t(msg).append(pgood);
501992083aSJim Wright }
51c1d4de5eSPatrick Williams catch (const sdbusplus::exception_t& e)
521992083aSJim Wright {
531992083aSJim Wright return sd_bus_error_set(error, e.name(), e.description());
541992083aSJim Wright }
551992083aSJim Wright }
561992083aSJim Wright else
571992083aSJim Wright {
581992083aSJim Wright // The message or context were null
59*31ae6ee8SAnwaar Hadi lg2::error("Unable to service get pgood property callback");
601992083aSJim Wright return -1;
611992083aSJim Wright }
621992083aSJim Wright
631992083aSJim Wright return 1;
641992083aSJim Wright }
651992083aSJim Wright
callbackGetPgoodTimeout(sd_bus *,const char *,const char *,const char *,sd_bus_message * msg,void * context,sd_bus_error * error)66f5402197SPatrick Williams int PowerInterface::callbackGetPgoodTimeout(
67f5402197SPatrick Williams sd_bus* /*bus*/, const char* /*path*/, const char* /*interface*/,
68f5402197SPatrick Williams const char* /*property*/, sd_bus_message* msg, void* context,
691992083aSJim Wright sd_bus_error* error)
701992083aSJim Wright {
711992083aSJim Wright if (msg != nullptr && context != nullptr)
721992083aSJim Wright {
731992083aSJim Wright try
741992083aSJim Wright {
751992083aSJim Wright auto pwrObj = static_cast<PowerInterface*>(context);
761992083aSJim Wright int timeout = pwrObj->getPgoodTimeout();
77*31ae6ee8SAnwaar Hadi lg2::debug("callbackGetPgoodTimeout: {TIMEOUT}", "TIMEOUT",
78*31ae6ee8SAnwaar Hadi timeout);
791992083aSJim Wright
807354ce62SPatrick Williams sdbusplus::message_t(msg).append(timeout);
811992083aSJim Wright }
82c1d4de5eSPatrick Williams catch (const sdbusplus::exception_t& e)
831992083aSJim Wright {
841992083aSJim Wright return sd_bus_error_set(error, e.name(), e.description());
851992083aSJim Wright }
861992083aSJim Wright }
871992083aSJim Wright else
881992083aSJim Wright {
891992083aSJim Wright // The message or context were null
90*31ae6ee8SAnwaar Hadi lg2::error("Unable to service get pgood timeout property callback");
911992083aSJim Wright return -1;
921992083aSJim Wright }
931992083aSJim Wright
941992083aSJim Wright return 1;
951992083aSJim Wright }
961992083aSJim Wright
callbackGetPowerState(sd_bus_message * msg,void * context,sd_bus_error * error)971992083aSJim Wright int PowerInterface::callbackGetPowerState(sd_bus_message* msg, void* context,
981992083aSJim Wright sd_bus_error* error)
991992083aSJim Wright {
1001992083aSJim Wright if (msg != nullptr && context != nullptr)
1011992083aSJim Wright {
1021992083aSJim Wright try
1031992083aSJim Wright {
1041992083aSJim Wright auto pwrObj = static_cast<PowerInterface*>(context);
1051992083aSJim Wright // Return the current power state of the GPIO, rather than the last
1061992083aSJim Wright // requested power state change
1071992083aSJim Wright int pgood = pwrObj->getPgood();
108*31ae6ee8SAnwaar Hadi lg2::debug("callbackGetPowerState: {PGOOD}", "PGOOD", pgood);
1091992083aSJim Wright
1107354ce62SPatrick Williams auto reply = sdbusplus::message_t(msg).new_method_return();
1111992083aSJim Wright reply.append(pgood);
1121992083aSJim Wright reply.method_return();
1131992083aSJim Wright }
114c1d4de5eSPatrick Williams catch (const sdbusplus::exception_t& e)
1151992083aSJim Wright {
1161992083aSJim Wright return sd_bus_error_set(error, e.name(), e.description());
1171992083aSJim Wright }
1181992083aSJim Wright }
1191992083aSJim Wright else
1201992083aSJim Wright {
1211992083aSJim Wright // The message or context were null
122*31ae6ee8SAnwaar Hadi lg2::error("Unable to service getPowerState method callback");
1231992083aSJim Wright return -1;
1241992083aSJim Wright }
1251992083aSJim Wright
1261992083aSJim Wright return 1;
1271992083aSJim Wright }
1281992083aSJim Wright
callbackSetPgoodTimeout(sd_bus *,const char *,const char *,const char *,sd_bus_message * msg,void * context,sd_bus_error * error)129f5402197SPatrick Williams int PowerInterface::callbackSetPgoodTimeout(
130f5402197SPatrick Williams sd_bus* /*bus*/, const char* /*path*/, const char* /*interface*/,
131f5402197SPatrick Williams const char* /*property*/, sd_bus_message* msg, void* context,
1321992083aSJim Wright sd_bus_error* error)
1331992083aSJim Wright {
1341992083aSJim Wright if (msg != nullptr && context != nullptr)
1351992083aSJim Wright {
1361992083aSJim Wright try
1371992083aSJim Wright {
1387354ce62SPatrick Williams auto m = sdbusplus::message_t(msg);
1391992083aSJim Wright
1401992083aSJim Wright int timeout{};
1411992083aSJim Wright m.read(timeout);
142*31ae6ee8SAnwaar Hadi lg2::info("callbackSetPgoodTimeout: {TIMEOUT}", "TIMEOUT", timeout);
143ccea2d2bSJim Wright
144ccea2d2bSJim Wright auto pwrObj = static_cast<PowerInterface*>(context);
1451992083aSJim Wright pwrObj->setPgoodTimeout(timeout);
1461992083aSJim Wright }
147c1d4de5eSPatrick Williams catch (const sdbusplus::exception_t& e)
1481992083aSJim Wright {
1491992083aSJim Wright return sd_bus_error_set(error, e.name(), e.description());
1501992083aSJim Wright }
1511992083aSJim Wright }
1521992083aSJim Wright else
1531992083aSJim Wright {
1541992083aSJim Wright // The message or context were null
155*31ae6ee8SAnwaar Hadi lg2::error("Unable to service set pgood timeout property callback");
1561992083aSJim Wright return -1;
1571992083aSJim Wright }
1581992083aSJim Wright
1591992083aSJim Wright return 1;
1601992083aSJim Wright }
1611992083aSJim Wright
callbackGetState(sd_bus *,const char *,const char *,const char *,sd_bus_message * msg,void * context,sd_bus_error * error)162f5402197SPatrick Williams int PowerInterface::callbackGetState(
163f5402197SPatrick Williams sd_bus* /*bus*/, const char* /*path*/, const char* /*interface*/,
164f5402197SPatrick Williams const char* /*property*/, sd_bus_message* msg, void* context,
1651992083aSJim Wright sd_bus_error* error)
1661992083aSJim Wright {
1671992083aSJim Wright if (msg != nullptr && context != nullptr)
1681992083aSJim Wright {
1691992083aSJim Wright try
1701992083aSJim Wright {
1711992083aSJim Wright auto pwrObj = static_cast<PowerInterface*>(context);
1721992083aSJim Wright int state = pwrObj->getState();
173*31ae6ee8SAnwaar Hadi lg2::debug("callbackGetState: {STATE}", "STATE", state);
1741992083aSJim Wright
1757354ce62SPatrick Williams sdbusplus::message_t(msg).append(state);
1761992083aSJim Wright }
177c1d4de5eSPatrick Williams catch (const sdbusplus::exception_t& e)
1781992083aSJim Wright {
1791992083aSJim Wright return sd_bus_error_set(error, e.name(), e.description());
1801992083aSJim Wright }
1811992083aSJim Wright }
1821992083aSJim Wright else
1831992083aSJim Wright {
1841992083aSJim Wright // The message or context were null
185*31ae6ee8SAnwaar Hadi lg2::error("Unable to service get state property callback");
1861992083aSJim Wright return -1;
1871992083aSJim Wright }
1881992083aSJim Wright
1891992083aSJim Wright return 1;
1901992083aSJim Wright }
1911992083aSJim Wright
callbackSetPowerState(sd_bus_message * msg,void * context,sd_bus_error * error)1921992083aSJim Wright int PowerInterface::callbackSetPowerState(sd_bus_message* msg, void* context,
1931992083aSJim Wright sd_bus_error* error)
1941992083aSJim Wright {
1951992083aSJim Wright if (msg != nullptr && context != nullptr)
1961992083aSJim Wright {
1971992083aSJim Wright try
1981992083aSJim Wright {
1997354ce62SPatrick Williams auto m = sdbusplus::message_t(msg);
2001992083aSJim Wright
2011992083aSJim Wright int state{};
2021992083aSJim Wright m.read(state);
2031992083aSJim Wright
2041992083aSJim Wright if (state != 1 && state != 0)
2051992083aSJim Wright {
2061992083aSJim Wright return sd_bus_error_set(error,
2071992083aSJim Wright "org.openbmc.ControlPower.Error.Failed",
2081992083aSJim Wright "Invalid power state");
2091992083aSJim Wright }
210*31ae6ee8SAnwaar Hadi lg2::info("callbackSetPowerState: {STATE}", "STATE", state);
211ccea2d2bSJim Wright
212ccea2d2bSJim Wright auto pwrObj = static_cast<PowerInterface*>(context);
2131992083aSJim Wright pwrObj->setState(state);
2141992083aSJim Wright
2151992083aSJim Wright m.new_method_return().method_return();
2161992083aSJim Wright }
217c1d4de5eSPatrick Williams catch (const sdbusplus::exception_t& e)
2181992083aSJim Wright {
2191992083aSJim Wright return sd_bus_error_set(error, e.name(), e.description());
2201992083aSJim Wright }
2211992083aSJim Wright }
2221992083aSJim Wright else
2231992083aSJim Wright {
2241992083aSJim Wright // The message or context were null
225*31ae6ee8SAnwaar Hadi lg2::error("Unable to service setPowerState method callback");
2261992083aSJim Wright return -1;
2271992083aSJim Wright }
2281992083aSJim Wright
2291992083aSJim Wright return 1;
2301992083aSJim Wright }
2311992083aSJim Wright
callbackSetPowerSupplyError(sd_bus_message * msg,void * context,sd_bus_error * error)232f5402197SPatrick Williams int PowerInterface::callbackSetPowerSupplyError(
233f5402197SPatrick Williams sd_bus_message* msg, void* context, sd_bus_error* error)
234ccea2d2bSJim Wright {
235ccea2d2bSJim Wright if (msg != nullptr && context != nullptr)
236ccea2d2bSJim Wright {
237ccea2d2bSJim Wright try
238ccea2d2bSJim Wright {
2397354ce62SPatrick Williams auto m = sdbusplus::message_t(msg);
240ccea2d2bSJim Wright
241ccea2d2bSJim Wright std::string psError{};
242ccea2d2bSJim Wright m.read(psError);
243*31ae6ee8SAnwaar Hadi lg2::info("callbackSetPowerSupplyError: {PSERROR}", "PSERROR",
244*31ae6ee8SAnwaar Hadi psError);
245ccea2d2bSJim Wright
246ccea2d2bSJim Wright auto pwrObj = static_cast<PowerInterface*>(context);
247ccea2d2bSJim Wright pwrObj->setPowerSupplyError(psError);
248ccea2d2bSJim Wright
249ccea2d2bSJim Wright m.new_method_return().method_return();
250ccea2d2bSJim Wright }
251ccea2d2bSJim Wright catch (const sdbusplus::exception_t& e)
252ccea2d2bSJim Wright {
253ccea2d2bSJim Wright return sd_bus_error_set(error, e.name(), e.description());
254ccea2d2bSJim Wright }
255ccea2d2bSJim Wright }
256ccea2d2bSJim Wright else
257ccea2d2bSJim Wright {
258ccea2d2bSJim Wright // The message or context were null
259*31ae6ee8SAnwaar Hadi lg2::error("Unable to service setPowerSupplyError method callback");
260ccea2d2bSJim Wright return -1;
261ccea2d2bSJim Wright }
262ccea2d2bSJim Wright
263ccea2d2bSJim Wright return 1;
264ccea2d2bSJim Wright }
265ccea2d2bSJim Wright
emitPowerGoodSignal()2661992083aSJim Wright void PowerInterface::emitPowerGoodSignal()
2671992083aSJim Wright {
268*31ae6ee8SAnwaar Hadi lg2::info("emitPowerGoodSignal");
269213ffe99SJim Wright serverInterface.new_signal("PowerGood").signal_send();
2701992083aSJim Wright }
2711992083aSJim Wright
emitPowerLostSignal()2721992083aSJim Wright void PowerInterface::emitPowerLostSignal()
2731992083aSJim Wright {
274*31ae6ee8SAnwaar Hadi lg2::info("emitPowerLostSignal");
275213ffe99SJim Wright serverInterface.new_signal("PowerLost").signal_send();
2761992083aSJim Wright }
2771992083aSJim Wright
emitPropertyChangedSignal(const char * property)2781992083aSJim Wright void PowerInterface::emitPropertyChangedSignal(const char* property)
2791992083aSJim Wright {
280*31ae6ee8SAnwaar Hadi lg2::info("emitPropertyChangedSignal: {PROPERTY}", "PROPERTY", property);
281213ffe99SJim Wright serverInterface.property_changed(property);
2821992083aSJim Wright }
2831992083aSJim Wright
284213ffe99SJim Wright const sdbusplus::vtable::vtable_t PowerInterface::vtable[] = {
2851992083aSJim Wright sdbusplus::vtable::start(),
2861992083aSJim Wright // Method setPowerState takes an int parameter and returns void
2871992083aSJim Wright sdbusplus::vtable::method("setPowerState", "i", "", callbackSetPowerState),
2881992083aSJim Wright // Method getPowerState takes no parameters and returns int
2891992083aSJim Wright sdbusplus::vtable::method("getPowerState", "", "i", callbackGetPowerState),
2901992083aSJim Wright // Signal PowerGood
2911992083aSJim Wright sdbusplus::vtable::signal("PowerGood", ""),
2921992083aSJim Wright // Signal PowerLost
2931992083aSJim Wright sdbusplus::vtable::signal("PowerLost", ""),
2941992083aSJim Wright // Property pgood is type int, read only, and uses the emits_change flag
2951992083aSJim Wright sdbusplus::vtable::property("pgood", "i", callbackGetPgood,
2961992083aSJim Wright sdbusplus::vtable::property_::emits_change),
2971992083aSJim Wright // Property state is type int, read only, and uses the emits_change flag
2981992083aSJim Wright sdbusplus::vtable::property("state", "i", callbackGetState,
2991992083aSJim Wright sdbusplus::vtable::property_::emits_change),
3001992083aSJim Wright // Property pgood_timeout is type int, read write, and uses the emits_change
3011992083aSJim Wright // flag
3021992083aSJim Wright sdbusplus::vtable::property("pgood_timeout", "i", callbackGetPgoodTimeout,
3031992083aSJim Wright callbackSetPgoodTimeout,
3041992083aSJim Wright sdbusplus::vtable::property_::emits_change),
305ccea2d2bSJim Wright // Method setPowerSupplyError takes a string parameter and returns void
306ccea2d2bSJim Wright sdbusplus::vtable::method("setPowerSupplyError", "s", "",
307ccea2d2bSJim Wright callbackSetPowerSupplyError),
3081992083aSJim Wright sdbusplus::vtable::end()};
3091992083aSJim Wright
3101992083aSJim Wright } // namespace phosphor::power::sequencer
311