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