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