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
getService(sdbusplus::bus_t & bus,const std::string & objectPath,const std::string & interface)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
isHostPoweringOff()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
getChassisPowerState()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.Chassis0",
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