1974c916eSMatt Spinler #pragma once 2974c916eSMatt Spinler 3974c916eSMatt Spinler #include <phosphor-logging/log.hpp> 4*882ce956SMatt Spinler #include <phosphor-logging/elog.hpp> 5974c916eSMatt Spinler #include <sdbusplus/bus.hpp> 6974c916eSMatt Spinler #include <string> 7974c916eSMatt Spinler 8974c916eSMatt Spinler namespace witherspoon 9974c916eSMatt Spinler { 10974c916eSMatt Spinler namespace power 11974c916eSMatt Spinler { 12974c916eSMatt Spinler namespace util 13974c916eSMatt Spinler { 14974c916eSMatt Spinler 15*882ce956SMatt Spinler constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1"; 16*882ce956SMatt Spinler constexpr auto SYSTEMD_ROOT = "/org/freedesktop/systemd1"; 17*882ce956SMatt Spinler constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager"; 18*882ce956SMatt Spinler constexpr auto POWEROFF_TARGET = "obmc-chassis-hard-poweroff@0.target"; 19974c916eSMatt Spinler constexpr auto PROPERTY_INTF = "org.freedesktop.DBus.Properties"; 20974c916eSMatt Spinler 21974c916eSMatt Spinler /** 22974c916eSMatt Spinler * @brief Get the service name from the mapper for the 23974c916eSMatt Spinler * interface and path passed in. 24974c916eSMatt Spinler * 25974c916eSMatt Spinler * @param[in] path - the D-Bus path name 26974c916eSMatt Spinler * @param[in] interface - the D-Bus interface name 27974c916eSMatt Spinler * @param[in] bus - the D-Bus object 28974c916eSMatt Spinler * 29974c916eSMatt Spinler * @return The service name 30974c916eSMatt Spinler */ 31974c916eSMatt Spinler std::string getService(const std::string& path, 32974c916eSMatt Spinler const std::string& interface, 33974c916eSMatt Spinler sdbusplus::bus::bus& bus); 34974c916eSMatt Spinler 35974c916eSMatt Spinler /** 36974c916eSMatt Spinler * @brief Read a D-Bus property 37974c916eSMatt Spinler * 38974c916eSMatt Spinler * @param[in] interface - the interface the property is on 39974c916eSMatt Spinler * @param[in] propertName - the name of the property 40974c916eSMatt Spinler * @param[in] path - the D-Bus path 41974c916eSMatt Spinler * @param[in] service - the D-Bus service 42974c916eSMatt Spinler * @param[in] bus - the D-Bus object 43974c916eSMatt Spinler * @param[out] value - filled in with the property value 44974c916eSMatt Spinler */ 45974c916eSMatt Spinler template<typename T> 46974c916eSMatt Spinler void getProperty(const std::string& interface, 47974c916eSMatt Spinler const std::string& propertyName, 48974c916eSMatt Spinler const std::string& path, 49974c916eSMatt Spinler const std::string& service, 50974c916eSMatt Spinler sdbusplus::bus::bus& bus, 51974c916eSMatt Spinler T& value) 52974c916eSMatt Spinler { 53974c916eSMatt Spinler sdbusplus::message::variant<T> property; 54974c916eSMatt Spinler 55974c916eSMatt Spinler auto method = bus.new_method_call(service.c_str(), 56974c916eSMatt Spinler path.c_str(), 57974c916eSMatt Spinler PROPERTY_INTF, 58974c916eSMatt Spinler "Get"); 59974c916eSMatt Spinler 60974c916eSMatt Spinler method.append(interface, propertyName); 61974c916eSMatt Spinler 62974c916eSMatt Spinler auto reply = bus.call(method); 63974c916eSMatt Spinler if (reply.is_method_error()) 64974c916eSMatt Spinler { 65974c916eSMatt Spinler using namespace phosphor::logging; 66974c916eSMatt Spinler log<level::ERR>("Error in property get call", 67974c916eSMatt Spinler entry("PATH=%s", path.c_str()), 68974c916eSMatt Spinler entry("PROPERTY=%s", propertyName.c_str())); 69*882ce956SMatt Spinler 70974c916eSMatt Spinler // TODO openbmc/openbmc#851 - Once available, throw returned error 71974c916eSMatt Spinler throw std::runtime_error("Error in property get call"); 72974c916eSMatt Spinler } 73974c916eSMatt Spinler 74974c916eSMatt Spinler reply.read(property); 75974c916eSMatt Spinler value = sdbusplus::message::variant_ns::get<T>(property); 76974c916eSMatt Spinler } 77974c916eSMatt Spinler 7848b4a430SMatt Spinler /** 79*882ce956SMatt Spinler * Logs an error and powers off the system. 8048b4a430SMatt Spinler * 81*882ce956SMatt Spinler * @tparam T - error that will be logged before the power off 8248b4a430SMatt Spinler * @param[in] bus - D-Bus object 8348b4a430SMatt Spinler */ 84*882ce956SMatt Spinler template<typename T> 85*882ce956SMatt Spinler void powerOff(sdbusplus::bus::bus& bus) 86*882ce956SMatt Spinler { 87*882ce956SMatt Spinler phosphor::logging::report<T>(); 88*882ce956SMatt Spinler 89*882ce956SMatt Spinler auto method = bus.new_method_call(SYSTEMD_SERVICE, 90*882ce956SMatt Spinler SYSTEMD_ROOT, 91*882ce956SMatt Spinler SYSTEMD_INTERFACE, 92*882ce956SMatt Spinler "StartUnit"); 93*882ce956SMatt Spinler 94*882ce956SMatt Spinler method.append(POWEROFF_TARGET); 95*882ce956SMatt Spinler method.append("replace"); 96*882ce956SMatt Spinler 97*882ce956SMatt Spinler bus.call_noreply(method); 98*882ce956SMatt Spinler } 9948b4a430SMatt Spinler 100974c916eSMatt Spinler } 101974c916eSMatt Spinler } 102974c916eSMatt Spinler } 103