1 #include "util.hpp" 2 3 #include <phosphor-logging/elog.hpp> 4 5 #include <format> 6 #include <sstream> 7 #include <variant> 8 #include <vector> 9 10 namespace openpower 11 { 12 namespace util 13 { 14 using namespace phosphor::logging; 15 16 std::string getService(sdbusplus::bus_t& bus, const std::string& objectPath, 17 const std::string& interface) 18 { 19 constexpr auto mapperBusBame = "xyz.openbmc_project.ObjectMapper"; 20 constexpr auto mapperObjectPath = "/xyz/openbmc_project/object_mapper"; 21 constexpr auto mapperInterface = "xyz.openbmc_project.ObjectMapper"; 22 std::vector<std::pair<std::string, std::vector<std::string>>> response; 23 auto method = bus.new_method_call(mapperBusBame, mapperObjectPath, 24 mapperInterface, "GetObject"); 25 method.append(objectPath, std::vector<std::string>({interface})); 26 try 27 { 28 auto reply = bus.call(method); 29 reply.read(response); 30 } 31 catch (const sdbusplus::exception_t& e) 32 { 33 log<level::ERR>(std::format("D-Bus call exception OBJPATH={}" 34 "INTERFACE={} EXCEPTION={}", 35 objectPath, interface, e.what()) 36 .c_str()); 37 38 throw std::runtime_error("Service name is not found"); 39 } 40 41 if (response.empty()) 42 { 43 throw std::runtime_error("Service name response is empty"); 44 } 45 return response.begin()->first; 46 } 47 48 bool isHostPoweringOff() 49 { 50 try 51 { 52 constexpr auto object = "/xyz/openbmc_project/state/host0"; 53 constexpr auto service = "xyz.openbmc_project.State.Host"; 54 constexpr auto interface = "xyz.openbmc_project.State.Host"; 55 constexpr auto property = "CurrentHostState"; 56 auto bus = sdbusplus::bus::new_default(); 57 58 std::variant<std::string> retval; 59 auto properties = bus.new_method_call( 60 service, object, "org.freedesktop.DBus.Properties", "Get"); 61 properties.append(interface); 62 properties.append(property); 63 auto result = bus.call(properties); 64 result.read(retval); 65 66 const std::string* state = std::get_if<std::string>(&retval); 67 if (state == nullptr) 68 { 69 std::string err = std::format( 70 "CurrentHostState property is not set ({})", object); 71 log<level::ERR>(err.c_str()); 72 return false; 73 } 74 if ((*state == "xyz.openbmc_project.State.Host.HostState." 75 "TransitioningToOff") || 76 (*state == "xyz.openbmc_project.State.Host.HostState." 77 "Off") || 78 (*state == "xyz.openbmc_project.State.Host.HostState." 79 "Quiesced")) 80 { 81 return true; 82 } 83 } 84 catch (const std::exception& ex) 85 { 86 log<level::ERR>( 87 std::format("Failed to read CurrentHostState property ({})", 88 ex.what()) 89 .c_str()); 90 } 91 return false; 92 } 93 94 std::string getChassisPowerState() 95 { 96 std::string powerState{}; 97 try 98 { 99 auto bus = sdbusplus::bus::new_default(); 100 auto properties = 101 bus.new_method_call("xyz.openbmc_project.State.Chassis", 102 "/xyz/openbmc_project/state/chassis0", 103 "org.freedesktop.DBus.Properties", "Get"); 104 properties.append("xyz.openbmc_project.State.Chassis"); 105 properties.append("CurrentPowerState"); 106 auto result = bus.call(properties); 107 std::variant<std::string> val; 108 result.read(val); 109 if (auto pVal = std::get_if<std::string>(&val)) 110 { 111 powerState = *pVal; 112 } 113 } 114 115 catch (const std::exception& ex) 116 { 117 log<level::ERR>( 118 std::format("Failed to read CurrentPowerState property ({})", 119 ex.what()) 120 .c_str()); 121 } 122 123 log<level::DEBUG>(std::format("Power state is: {} ", powerState).c_str()); 124 125 return powerState; 126 } 127 128 } // namespace util 129 } // namespace openpower 130