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