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