1 #include "dump_utils.hpp"
2 
3 #include <fmt/core.h>
4 
5 #include <phosphor-logging/log.hpp>
6 
7 namespace phosphor
8 {
9 namespace dump
10 {
11 
12 using namespace phosphor::logging;
13 
14 std::string getService(sdbusplus::bus_t& bus, const std::string& path,
15                        const std::string& interface)
16 {
17     constexpr auto objectMapperName = "xyz.openbmc_project.ObjectMapper";
18     constexpr auto objectMapperPath = "/xyz/openbmc_project/object_mapper";
19 
20     auto method = bus.new_method_call(objectMapperName, objectMapperPath,
21                                       objectMapperName, "GetObject");
22 
23     method.append(path);
24     method.append(std::vector<std::string>({interface}));
25 
26     std::vector<std::pair<std::string, std::vector<std::string>>> response;
27 
28     try
29     {
30         auto reply = bus.call(method);
31         reply.read(response);
32         if (response.empty())
33         {
34             log<level::ERR>(fmt::format("Error in mapper response for getting "
35                                         "service name, PATH({}), INTERFACE({})",
36                                         path, interface)
37                                 .c_str());
38             return std::string{};
39         }
40     }
41     catch (const sdbusplus::exception_t& e)
42     {
43         log<level::ERR>(fmt::format("Error in mapper method call, "
44                                     "errormsg({}), PATH({}), INTERFACE({})",
45                                     e.what(), path, interface)
46                             .c_str());
47         return std::string{};
48     }
49     return response[0].first;
50 }
51 
52 BootProgress getBootProgress()
53 {
54     constexpr auto bootProgressInterface =
55         "xyz.openbmc_project.State.Boot.Progress";
56     // TODO Need to change host instance if multiple instead "0"
57     constexpr auto hostStateObjPath = "/xyz/openbmc_project/state/host0";
58 
59     BootProgress bootProgessStage;
60 
61     try
62     {
63         auto bus = sdbusplus::bus::new_default();
64         auto service = getService(bus, hostStateObjPath, bootProgressInterface);
65 
66         auto method =
67             bus.new_method_call(service.c_str(), hostStateObjPath,
68                                 "org.freedesktop.DBus.Properties", "Get");
69 
70         method.append(bootProgressInterface, "BootProgress");
71 
72         auto reply = bus.call(method);
73 
74         using DBusValue_t =
75             std::variant<std::string, bool, std::vector<uint8_t>,
76                          std::vector<std::string>>;
77         DBusValue_t propertyVal;
78 
79         reply.read(propertyVal);
80 
81         // BootProgress property type is string
82         std::string bootPgs(std::get<std::string>(propertyVal));
83 
84         bootProgessStage = sdbusplus::xyz::openbmc_project::State::Boot::
85             server::Progress::convertProgressStagesFromString(bootPgs);
86     }
87     catch (const sdbusplus::exception_t& e)
88     {
89         log<level::ERR>(fmt::format("D-Bus call exception, OBJPATH({}), "
90                                     "INTERFACE({}), EXCEPTION({})",
91                                     hostStateObjPath, bootProgressInterface,
92                                     e.what())
93                             .c_str());
94         throw std::runtime_error("Failed to get BootProgress stage");
95     }
96     catch (const std::bad_variant_access& e)
97     {
98         log<level::ERR>(
99             fmt::format("Exception raised while read BootProgress property "
100                         "value,  OBJPATH({}), INTERFACE({}), EXCEPTION({})",
101                         hostStateObjPath, bootProgressInterface, e.what())
102                 .c_str());
103         throw std::runtime_error("Failed to get BootProgress stage");
104     }
105 
106     return bootProgessStage;
107 }
108 
109 bool isHostRunning()
110 {
111     // TODO #ibm-openbmc/dev/2858 Revisit the method for finding whether host
112     // is running.
113     BootProgress bootProgressStatus = phosphor::dump::getBootProgress();
114     if ((bootProgressStatus == BootProgress::SystemInitComplete) ||
115         (bootProgressStatus == BootProgress::OSStart) ||
116         (bootProgressStatus == BootProgress::OSRunning))
117     {
118         return true;
119     }
120     return false;
121 }
122 } // namespace dump
123 } // namespace phosphor
124