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