xref: /openbmc/phosphor-power/phosphor-power-sequencer/src/power_interface.cpp (revision 31ae6ee8c0e17f121e5cb3e581361296d69fdf2d)
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