xref: /openbmc/openpower-debug-collector/watchdog/watchdog_dbus.cpp (revision 5ba35c6349f4d523d3f5b5e001c869392b2c5674)
1 #include "watchdog_dbus.hpp"
2 
3 #include "watchdog_logging.hpp"
4 
5 #include <unistd.h>
6 
7 #include <phosphor-logging/lg2.hpp>
8 
9 #include <string>
10 #include <vector>
11 
12 namespace watchdog
13 {
14 namespace dump
15 {
16 
dbusMethod(const std::string & path,const std::string & interface,const std::string & function,sdbusplus::message_t & method,const std::string & extended)17 int dbusMethod(const std::string& path, const std::string& interface,
18                const std::string& function, sdbusplus::message_t& method,
19                const std::string& extended)
20 {
21     int rc = RC_DBUS_ERROR; // assume error
22 
23     try
24     {
25         constexpr auto serviceFind = "xyz.openbmc_project.ObjectMapper";
26         constexpr auto pathFind = "/xyz/openbmc_project/object_mapper";
27         constexpr auto interfaceFind = "xyz.openbmc_project.ObjectMapper";
28         constexpr auto functionFind = "GetObject";
29 
30         auto bus = sdbusplus::bus::new_system(); // using system dbus
31 
32         // method to find service from object path and object interface
33         auto newMethod = bus.new_method_call(serviceFind, pathFind,
34                                              interfaceFind, functionFind);
35 
36         // find the service for specified object path and interface
37         newMethod.append(path.c_str());
38         newMethod.append(std::vector<std::string>({interface}));
39         auto reply = bus.call(newMethod);
40 
41         // dbus call results
42         std::map<std::string, std::vector<std::string>> responseFindService;
43         reply.read(responseFindService);
44 
45         // If we successfully found the service associated with the dbus object
46         // path and interface then create a method for the specified interface
47         // and function.
48         if (!responseFindService.empty())
49         {
50             auto service = responseFindService.begin()->first;
51 
52             // Some methods (e.g. get attribute) take an extended parameter
53             if (extended == "")
54             {
55                 // return the method
56                 method =
57                     bus.new_method_call(service.c_str(), path.c_str(),
58                                         interface.c_str(), function.c_str());
59             }
60             else
61             {
62                 // return extended method
63                 method =
64                     bus.new_method_call(service.c_str(), path.c_str(),
65                                         extended.c_str(), function.c_str());
66             }
67 
68             rc = RC_SUCCESS;
69         }
70         else
71         {
72             // This trace will be picked up in event log
73             lg2::info("dbusMethod service not found");
74             std::string traceMsgPath = std::string(path, maxTraceLen);
75             lg2::info(traceMsgPath.c_str());
76             std::string traceMsgIface = std::string(interface, maxTraceLen);
77             lg2::info(traceMsgIface.c_str());
78         }
79     }
80     catch (const sdbusplus::exception_t& e)
81     {
82         lg2::error("Error in dbusMethod ({ERROR})", "ERROR", e);
83     }
84 
85     return rc;
86 }
87 
createPel(const std::string & eventType,std::map<std::string,std::string> & additional,const std::vector<FFDCTuple> & ffdc)88 uint32_t createPel(const std::string& eventType,
89                    std::map<std::string, std::string>& additional,
90                    const std::vector<FFDCTuple>& ffdc)
91 {
92     // Create returns plid
93     int plid = 0;
94 
95     // Need to provide pid when using create or create-with-ffdc methods
96     additional.emplace("_PID", std::to_string(getpid()));
97 
98     // Sdbus call specifics
99     constexpr auto interface = "org.open_power.Logging.PEL";
100     constexpr auto function = "CreatePELWithFFDCFiles";
101 
102     sdbusplus::message_t method;
103 
104     if (0 == dbusMethod(pathLogging, interface, function, method))
105     {
106         try
107         {
108             // append additional dbus call parameters
109             method.append(eventType, levelPelError, additional, ffdc);
110 
111             // using system dbus
112             auto bus = sdbusplus::bus::new_system();
113             auto response = bus.call(method);
114 
115             // reply will be tuple containing bmc log id, platform log id
116             std::tuple<uint32_t, uint32_t> reply = {0, 0};
117 
118             // parse dbus response into reply
119             response.read(reply);
120             plid = std::get<1>(reply); // platform log id is tuple "second"
121         }
122         catch (const sdbusplus::exception_t& e)
123         {
124             lg2::error("Error in createPel CreatePELWithFFDCFiles ({ERROR})",
125                        "ERROR", e);
126         }
127     }
128 
129     return plid; // platform log id or 0
130 }
131 
isHostStateRunning()132 bool isHostStateRunning()
133 {
134     constexpr auto path = "/xyz/openbmc_project/state/host0";
135     constexpr auto interface = "xyz.openbmc_project.State.Host";
136     constexpr auto extended = "org.freedesktop.DBus.Properties";
137     constexpr auto function = "Get";
138 
139     sdbusplus::message_t method;
140 
141     if (0 == dbusMethod(path, interface, function, method, extended))
142     {
143         try
144         {
145             method.append(interface, "CurrentHostState");
146             auto bus = sdbusplus::bus::new_system();
147             auto response = bus.call(method);
148             std::variant<std::string> reply;
149 
150             response.read(reply);
151             std::string currentHostState(std::get<std::string>(reply));
152 
153             if (currentHostState ==
154                 "xyz.openbmc_project.State.Host.HostState.Running")
155             {
156                 return true;
157             }
158         }
159         catch (const sdbusplus::exception_t& e)
160         {
161             lg2::error("Failed to read CurrentHostState property ({ERROR})",
162                        "ERROR", e);
163         }
164     }
165 
166     return false;
167 }
168 
169 } // namespace dump
170 } // namespace watchdog
171