1974c916eSMatt Spinler #pragma once 2974c916eSMatt Spinler 3882ce956SMatt Spinler #include <phosphor-logging/elog.hpp> 4*f0f02b9aSMatt Spinler #include <phosphor-logging/log.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 15882ce956SMatt Spinler constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1"; 16882ce956SMatt Spinler constexpr auto SYSTEMD_ROOT = "/org/freedesktop/systemd1"; 17882ce956SMatt Spinler constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager"; 18882ce956SMatt 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 */ 31*f0f02b9aSMatt Spinler std::string getService(const std::string& path, const std::string& interface, 32974c916eSMatt Spinler sdbusplus::bus::bus& bus); 33974c916eSMatt Spinler 34974c916eSMatt Spinler /** 35974c916eSMatt Spinler * @brief Read a D-Bus property 36974c916eSMatt Spinler * 37974c916eSMatt Spinler * @param[in] interface - the interface the property is on 38974c916eSMatt Spinler * @param[in] propertName - the name of the property 39974c916eSMatt Spinler * @param[in] path - the D-Bus path 40974c916eSMatt Spinler * @param[in] service - the D-Bus service 41974c916eSMatt Spinler * @param[in] bus - the D-Bus object 42974c916eSMatt Spinler * @param[out] value - filled in with the property value 43974c916eSMatt Spinler */ 44974c916eSMatt Spinler template <typename T> 45*f0f02b9aSMatt Spinler void getProperty(const std::string& interface, const std::string& propertyName, 46*f0f02b9aSMatt Spinler const std::string& path, const std::string& service, 47*f0f02b9aSMatt Spinler sdbusplus::bus::bus& bus, T& value) 48974c916eSMatt Spinler { 49974c916eSMatt Spinler sdbusplus::message::variant<T> property; 50974c916eSMatt Spinler 51*f0f02b9aSMatt Spinler auto method = bus.new_method_call(service.c_str(), path.c_str(), 52*f0f02b9aSMatt Spinler PROPERTY_INTF, "Get"); 53974c916eSMatt Spinler 54974c916eSMatt Spinler method.append(interface, propertyName); 55974c916eSMatt Spinler 56974c916eSMatt Spinler auto reply = bus.call(method); 57974c916eSMatt Spinler if (reply.is_method_error()) 58974c916eSMatt Spinler { 59974c916eSMatt Spinler using namespace phosphor::logging; 60974c916eSMatt Spinler log<level::ERR>("Error in property get call", 61974c916eSMatt Spinler entry("PATH=%s", path.c_str()), 62974c916eSMatt Spinler entry("PROPERTY=%s", propertyName.c_str())); 63882ce956SMatt Spinler 64974c916eSMatt Spinler // TODO openbmc/openbmc#851 - Once available, throw returned error 65974c916eSMatt Spinler throw std::runtime_error("Error in property get call"); 66974c916eSMatt Spinler } 67974c916eSMatt Spinler 68974c916eSMatt Spinler reply.read(property); 69974c916eSMatt Spinler value = sdbusplus::message::variant_ns::get<T>(property); 70974c916eSMatt Spinler } 71974c916eSMatt Spinler 7248b4a430SMatt Spinler /** 730a4f519bSBrandon Wyman * @brief Write a D-Bus property 740a4f519bSBrandon Wyman * 750a4f519bSBrandon Wyman * @param[in] interface - the interface the property is on 760a4f519bSBrandon Wyman * @param[in] propertName - the name of the property 770a4f519bSBrandon Wyman * @param[in] path - the D-Bus path 780a4f519bSBrandon Wyman * @param[in] service - the D-Bus service 790a4f519bSBrandon Wyman * @param[in] bus - the D-Bus object 800a4f519bSBrandon Wyman * @param[in] value - the value to set the property to 810a4f519bSBrandon Wyman */ 820a4f519bSBrandon Wyman template <typename T> 83*f0f02b9aSMatt Spinler void setProperty(const std::string& interface, const std::string& propertyName, 84*f0f02b9aSMatt Spinler const std::string& path, const std::string& service, 85*f0f02b9aSMatt Spinler sdbusplus::bus::bus& bus, T& value) 860a4f519bSBrandon Wyman { 870a4f519bSBrandon Wyman sdbusplus::message::variant<T> propertyValue(value); 880a4f519bSBrandon Wyman 89*f0f02b9aSMatt Spinler auto method = bus.new_method_call(service.c_str(), path.c_str(), 90*f0f02b9aSMatt Spinler PROPERTY_INTF, "Set"); 910a4f519bSBrandon Wyman 920a4f519bSBrandon Wyman method.append(interface, propertyName, propertyValue); 930a4f519bSBrandon Wyman 940a4f519bSBrandon Wyman auto reply = bus.call(method); 950a4f519bSBrandon Wyman if (reply.is_method_error()) 960a4f519bSBrandon Wyman { 970a4f519bSBrandon Wyman using namespace phosphor::logging; 980a4f519bSBrandon Wyman log<level::ERR>("Error in property set call", 990a4f519bSBrandon Wyman entry("SERVICE=%s", service.c_str()), 1000a4f519bSBrandon Wyman entry("PATH=%s", path.c_str()), 1010a4f519bSBrandon Wyman entry("PROPERTY=%s", propertyName.c_str())); 1020a4f519bSBrandon Wyman 1030a4f519bSBrandon Wyman // TODO openbmc/openbmc#851 - Once available, throw returned error 1040a4f519bSBrandon Wyman throw std::runtime_error("Error in property set call"); 1050a4f519bSBrandon Wyman } 1060a4f519bSBrandon Wyman } 1070a4f519bSBrandon Wyman 1080a4f519bSBrandon Wyman /** 109882ce956SMatt Spinler * Logs an error and powers off the system. 11048b4a430SMatt Spinler * 111882ce956SMatt Spinler * @tparam T - error that will be logged before the power off 11248b4a430SMatt Spinler * @param[in] bus - D-Bus object 11348b4a430SMatt Spinler */ 114882ce956SMatt Spinler template <typename T> 115882ce956SMatt Spinler void powerOff(sdbusplus::bus::bus& bus) 116882ce956SMatt Spinler { 117882ce956SMatt Spinler phosphor::logging::report<T>(); 118882ce956SMatt Spinler 119*f0f02b9aSMatt Spinler auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_ROOT, 120*f0f02b9aSMatt Spinler SYSTEMD_INTERFACE, "StartUnit"); 121882ce956SMatt Spinler 122882ce956SMatt Spinler method.append(POWEROFF_TARGET); 123882ce956SMatt Spinler method.append("replace"); 124882ce956SMatt Spinler 125882ce956SMatt Spinler bus.call_noreply(method); 126882ce956SMatt Spinler } 12748b4a430SMatt Spinler 128*f0f02b9aSMatt Spinler } // namespace util 129*f0f02b9aSMatt Spinler } // namespace power 130*f0f02b9aSMatt Spinler } // namespace witherspoon 131