blob: a9af4c602c11915eb2adffb391c9fec19a58cefe [file] [log] [blame]
Ben Tynerb8335562021-07-16 12:43:52 -05001#include <attn_common.hpp>
Ben Tyner4bbcb382021-02-22 09:29:00 -06002#include <attn_dbus.hpp>
Ben Tyner188f1092021-02-01 09:33:06 -06003#include <attn_logging.hpp>
4
5#include <string>
6#include <vector>
7
8namespace attn
9{
10
Ben Tyner5c5db652021-02-22 18:22:35 -060011/** @brief Create a dbus method */
Ben Tyner188f1092021-02-01 09:33:06 -060012int dbusMethod(const std::string& i_path, const std::string& i_interface,
13 const std::string& i_function,
Ben Tyner4bbcb382021-02-22 09:29:00 -060014 sdbusplus::message::message& o_method,
Ben Tyner5c5db652021-02-22 18:22:35 -060015 const std::string& i_extended)
Ben Tyner188f1092021-02-01 09:33:06 -060016{
Ben Tyner4bbcb382021-02-22 09:29:00 -060017 int rc = RC_DBUS_ERROR; // assume error
Ben Tyner188f1092021-02-01 09:33:06 -060018
19 try
20 {
21 constexpr auto serviceFind = "xyz.openbmc_project.ObjectMapper";
22 constexpr auto pathFind = "/xyz/openbmc_project/object_mapper";
23 constexpr auto interfaceFind = "xyz.openbmc_project.ObjectMapper";
24 constexpr auto functionFind = "GetObject";
25
26 auto bus = sdbusplus::bus::new_system(); // using system dbus
27
28 // method to find service from object path and object interface
29 auto method = bus.new_method_call(serviceFind, pathFind, interfaceFind,
30 functionFind);
31
32 // find the service for specified object path and interface
33 method.append(i_path.c_str());
34 method.append(std::vector<std::string>({i_interface}));
35 auto reply = bus.call(method);
36
37 // dbus call results
38 std::map<std::string, std::vector<std::string>> responseFindService;
39 reply.read(responseFindService);
40
41 // If we successfully found the service associated with the dbus object
42 // path and interface then create a method for the specified interface
43 // and function.
44 if (!responseFindService.empty())
45 {
46 auto service = responseFindService.begin()->first;
47
Ben Tyner4bbcb382021-02-22 09:29:00 -060048 // Some methods (e.g. get attribute) take an extended parameter
49 if (i_extended == "")
50 {
51 // return the method
52 o_method = bus.new_method_call(service.c_str(), i_path.c_str(),
53 i_interface.c_str(),
54 i_function.c_str());
55 }
56 else
57 {
58 // return extended method
59 o_method =
60 bus.new_method_call(service.c_str(), i_path.c_str(),
61 i_extended.c_str(), i_function.c_str());
62 }
Ben Tyner188f1092021-02-01 09:33:06 -060063
Ben Tyner4bbcb382021-02-22 09:29:00 -060064 rc = RC_SUCCESS;
Ben Tyner188f1092021-02-01 09:33:06 -060065 }
66 else
67 {
Ben Tyner6764d702021-02-12 09:17:23 -060068 // This trace will be picked up in event log
69 trace<level::INFO>("dbusMethod service not found");
70 std::string traceMsgPath = std::string(i_path, maxTraceLen);
71 trace<level::INFO>(traceMsgPath.c_str());
72 std::string traceMsgIface = std::string(i_interface, maxTraceLen);
73 trace<level::INFO>(traceMsgIface.c_str());
Ben Tyner188f1092021-02-01 09:33:06 -060074 }
75 }
76 catch (const sdbusplus::exception::SdBusError& e)
77 {
Ben Tyner5c5db652021-02-22 18:22:35 -060078 trace<level::ERROR>("dbusMethod exception");
Ben Tyner6764d702021-02-12 09:17:23 -060079 std::string traceMsg = std::string(e.what(), maxTraceLen);
80 trace<level::ERROR>(traceMsg.c_str());
Ben Tyner188f1092021-02-01 09:33:06 -060081 }
82
83 return rc;
84}
85
86/** @brief Create a PEL for the specified event type */
87uint32_t createPel(const std::string& i_event,
88 std::map<std::string, std::string>& i_additional,
89 const std::vector<util::FFDCTuple>& i_ffdc)
90{
91 // CreatePELWithFFDCFiles returns plid
92 int plid = 0;
93
94 // Need to provide pid when using create or create-with-ffdc methods
95 i_additional.emplace("_PID", std::to_string(getpid()));
96
97 // Sdbus call specifics
98 constexpr auto interface = "org.open_power.Logging.PEL";
99 constexpr auto function = "CreatePELWithFFDCFiles";
100
101 sdbusplus::message::message method;
102
103 if (0 == dbusMethod(pathLogging, interface, function, method))
104 {
105 try
106 {
107 // append additional dbus call paramaters
108 method.append(i_event, levelPelError, i_additional, i_ffdc);
109
110 // using system dbus
111 auto bus = sdbusplus::bus::new_system();
112 auto response = bus.call(method);
113
114 // reply will be tuple containing bmc log id, platform log id
115 std::tuple<uint32_t, uint32_t> reply = {0, 0};
116
Ben Tyner4bbcb382021-02-22 09:29:00 -0600117 // parse dbus response into reply
Ben Tyner188f1092021-02-01 09:33:06 -0600118 response.read(reply);
119 plid = std::get<1>(reply); // platform log id is tuple "second"
120 }
121 catch (const sdbusplus::exception::SdBusError& e)
122 {
Ben Tyner5c5db652021-02-22 18:22:35 -0600123 trace<level::ERROR>("createPel exception");
Ben Tyner6764d702021-02-12 09:17:23 -0600124 std::string traceMsg = std::string(e.what(), maxTraceLen);
125 trace<level::ERROR>(traceMsg.c_str());
Ben Tyner188f1092021-02-01 09:33:06 -0600126 }
127 }
128
129 return plid; // platform log id or 0
130}
131
132/** @brief Create a PEL from raw PEL data */
133void createPelRaw(const std::vector<uint8_t>& i_buffer)
134{
135 // Create FFDC file from buffer data
136 util::FFDCFile pelFile{util::FFDCFormat::Text};
137 auto fd = pelFile.getFileDescriptor();
Ben Tyner188f1092021-02-01 09:33:06 -0600138
139 auto filePath = pelFile.getPath(); // path to ffdc file
140
Ben Tynerd7006092021-02-05 14:55:52 -0600141 size_t numBytes = write(fd, i_buffer.data(), i_buffer.size());
142 if (i_buffer.size() != numBytes)
143 {
144 std::stringstream traceMsg;
145 traceMsg << filePath.c_str() << " only " << (int)numBytes << " of "
146 << (int)i_buffer.size() << " bytes written";
147 auto strobj = traceMsg.str();
148 trace<level::ERROR>(strobj.c_str());
149 }
150
151 lseek(fd, 0, SEEK_SET);
152
Ben Tyner188f1092021-02-01 09:33:06 -0600153 // Additional data for log
154 std::map<std::string, std::string> additional;
155 additional.emplace("RAWPEL", filePath.string());
156 additional.emplace("_PID", std::to_string(getpid()));
157
158 // dbus specifics
159 constexpr auto interface = "xyz.openbmc_project.Logging.Create";
160 constexpr auto function = "Create";
161
162 sdbusplus::message::message method;
163
164 if (0 == dbusMethod(pathLogging, interface, function, method))
165 {
166 try
167 {
168 // append additional dbus call parameters
169 method.append(eventPelTerminate, levelPelError, additional);
170
171 // using system dbus, no reply
172 auto bus = sdbusplus::bus::new_system();
173 bus.call_noreply(method);
174 }
175 catch (const sdbusplus::exception::SdBusError& e)
176 {
Ben Tyner5c5db652021-02-22 18:22:35 -0600177 trace<level::ERROR>("createPelRaw exception");
Ben Tyner6764d702021-02-12 09:17:23 -0600178 std::string traceMsg = std::string(e.what(), maxTraceLen);
179 trace<level::ERROR>(traceMsg.c_str());
Ben Tyner188f1092021-02-01 09:33:06 -0600180 }
181 }
182}
183
184/** @brief Get file descriptor of exisitng PEL */
185int getPel(const uint32_t i_pelId)
186{
187 // GetPEL returns file descriptor (int)
188 int fd = -1;
189
190 // dbus specifics
191 constexpr auto interface = "org.open_power.Logging.PEL";
192 constexpr auto function = "GetPEL";
193
194 sdbusplus::message::message method;
195
196 if (0 == dbusMethod(pathLogging, interface, function, method))
197 {
198 try
199 {
200 // additional dbus call parameters
201 method.append(i_pelId);
202
203 // using system dbus
204 auto bus = sdbusplus::bus::new_system();
205 auto response = bus.call(method);
206
207 // reply will be a unix file descriptor
208 sdbusplus::message::unix_fd reply;
209
Ben Tyner4bbcb382021-02-22 09:29:00 -0600210 // parse dbus response into reply
Ben Tyner188f1092021-02-01 09:33:06 -0600211 response.read(reply);
212
213 fd = dup(reply); // need to copy (dup) the file descriptor
214 }
215 catch (const sdbusplus::exception::SdBusError& e)
216 {
Ben Tyner5c5db652021-02-22 18:22:35 -0600217 trace<level::ERROR>("getPel exception");
Ben Tyner6764d702021-02-12 09:17:23 -0600218 std::string traceMsg = std::string(e.what(), maxTraceLen);
219 trace<level::ERROR>(traceMsg.c_str());
Ben Tyner188f1092021-02-01 09:33:06 -0600220 }
221 }
222
223 return fd; // file descriptor or -1
224}
225
Ben Tyner188f1092021-02-01 09:33:06 -0600226} // namespace attn