blob: c40d146dfc9b0c529540539afe61b79ae2c131ad [file] [log] [blame]
Zane Shelleyf36466f2022-02-11 15:10:55 -06001#include <attn/attn_common.hpp>
2#include <attn/attn_dbus.hpp>
3#include <attn/attn_logging.hpp>
austinfcuibfa831a2022-01-26 15:37:07 -06004#include <util/trace.hpp>
Ben Tyner188f1092021-02-01 09:33:06 -06005
6#include <string>
7#include <vector>
8
9namespace attn
10{
11
Ben Tyner5c5db652021-02-22 18:22:35 -060012/** @brief Create a dbus method */
Ben Tyner188f1092021-02-01 09:33:06 -060013int dbusMethod(const std::string& i_path, const std::string& i_interface,
14 const std::string& i_function,
Ben Tyner4bbcb382021-02-22 09:29:00 -060015 sdbusplus::message::message& o_method,
Ben Tyner5c5db652021-02-22 18:22:35 -060016 const std::string& i_extended)
Ben Tyner188f1092021-02-01 09:33:06 -060017{
Ben Tyner4bbcb382021-02-22 09:29:00 -060018 int rc = RC_DBUS_ERROR; // assume error
Ben Tyner188f1092021-02-01 09:33:06 -060019
20 try
21 {
22 constexpr auto serviceFind = "xyz.openbmc_project.ObjectMapper";
23 constexpr auto pathFind = "/xyz/openbmc_project/object_mapper";
24 constexpr auto interfaceFind = "xyz.openbmc_project.ObjectMapper";
25 constexpr auto functionFind = "GetObject";
26
27 auto bus = sdbusplus::bus::new_system(); // using system dbus
28
29 // method to find service from object path and object interface
30 auto method = bus.new_method_call(serviceFind, pathFind, interfaceFind,
31 functionFind);
32
33 // find the service for specified object path and interface
34 method.append(i_path.c_str());
35 method.append(std::vector<std::string>({i_interface}));
36 auto reply = bus.call(method);
37
38 // dbus call results
39 std::map<std::string, std::vector<std::string>> responseFindService;
40 reply.read(responseFindService);
41
42 // If we successfully found the service associated with the dbus object
43 // path and interface then create a method for the specified interface
44 // and function.
45 if (!responseFindService.empty())
46 {
47 auto service = responseFindService.begin()->first;
48
Ben Tyner4bbcb382021-02-22 09:29:00 -060049 // Some methods (e.g. get attribute) take an extended parameter
50 if (i_extended == "")
51 {
52 // return the method
53 o_method = bus.new_method_call(service.c_str(), i_path.c_str(),
54 i_interface.c_str(),
55 i_function.c_str());
56 }
57 else
58 {
59 // return extended method
60 o_method =
61 bus.new_method_call(service.c_str(), i_path.c_str(),
62 i_extended.c_str(), i_function.c_str());
63 }
Ben Tyner188f1092021-02-01 09:33:06 -060064
Ben Tyner4bbcb382021-02-22 09:29:00 -060065 rc = RC_SUCCESS;
Ben Tyner188f1092021-02-01 09:33:06 -060066 }
67 else
68 {
Ben Tyner6764d702021-02-12 09:17:23 -060069 // This trace will be picked up in event log
austinfcuibfa831a2022-01-26 15:37:07 -060070 trace::inf("dbusMethod service not found");
71 trace::inf(i_path.c_str());
72 trace::inf(i_interface.c_str());
Ben Tyner188f1092021-02-01 09:33:06 -060073 }
74 }
75 catch (const sdbusplus::exception::SdBusError& e)
76 {
austinfcuibfa831a2022-01-26 15:37:07 -060077 trace::err("dbusMethod exception");
78 trace::err(e.what());
Ben Tyner188f1092021-02-01 09:33:06 -060079 }
80
81 return rc;
82}
83
84/** @brief Create a PEL for the specified event type */
85uint32_t createPel(const std::string& i_event,
86 std::map<std::string, std::string>& i_additional,
87 const std::vector<util::FFDCTuple>& i_ffdc)
88{
89 // CreatePELWithFFDCFiles returns plid
90 int plid = 0;
91
92 // Need to provide pid when using create or create-with-ffdc methods
93 i_additional.emplace("_PID", std::to_string(getpid()));
94
95 // Sdbus call specifics
96 constexpr auto interface = "org.open_power.Logging.PEL";
97 constexpr auto function = "CreatePELWithFFDCFiles";
98
99 sdbusplus::message::message method;
100
101 if (0 == dbusMethod(pathLogging, interface, function, method))
102 {
103 try
104 {
105 // append additional dbus call paramaters
106 method.append(i_event, levelPelError, i_additional, i_ffdc);
107
108 // using system dbus
109 auto bus = sdbusplus::bus::new_system();
110 auto response = bus.call(method);
111
112 // reply will be tuple containing bmc log id, platform log id
113 std::tuple<uint32_t, uint32_t> reply = {0, 0};
114
Ben Tyner4bbcb382021-02-22 09:29:00 -0600115 // parse dbus response into reply
Ben Tyner188f1092021-02-01 09:33:06 -0600116 response.read(reply);
117 plid = std::get<1>(reply); // platform log id is tuple "second"
118 }
119 catch (const sdbusplus::exception::SdBusError& e)
120 {
austinfcuibfa831a2022-01-26 15:37:07 -0600121 trace::err("createPel exception");
122 trace::err(e.what());
Ben Tyner188f1092021-02-01 09:33:06 -0600123 }
124 }
125
126 return plid; // platform log id or 0
127}
128
129/** @brief Create a PEL from raw PEL data */
130void createPelRaw(const std::vector<uint8_t>& i_buffer)
131{
132 // Create FFDC file from buffer data
133 util::FFDCFile pelFile{util::FFDCFormat::Text};
134 auto fd = pelFile.getFileDescriptor();
Ben Tyner188f1092021-02-01 09:33:06 -0600135
136 auto filePath = pelFile.getPath(); // path to ffdc file
137
Ben Tynerd7006092021-02-05 14:55:52 -0600138 size_t numBytes = write(fd, i_buffer.data(), i_buffer.size());
139 if (i_buffer.size() != numBytes)
140 {
austinfcuibfa831a2022-01-26 15:37:07 -0600141 trace::err("%s only %u of %u bytes written", filePath.c_str(), numBytes,
142 i_buffer.size());
Ben Tynerd7006092021-02-05 14:55:52 -0600143 }
144
145 lseek(fd, 0, SEEK_SET);
146
Ben Tyner188f1092021-02-01 09:33:06 -0600147 // Additional data for log
148 std::map<std::string, std::string> additional;
149 additional.emplace("RAWPEL", filePath.string());
150 additional.emplace("_PID", std::to_string(getpid()));
151
152 // dbus specifics
153 constexpr auto interface = "xyz.openbmc_project.Logging.Create";
154 constexpr auto function = "Create";
155
156 sdbusplus::message::message method;
157
158 if (0 == dbusMethod(pathLogging, interface, function, method))
159 {
160 try
161 {
162 // append additional dbus call parameters
163 method.append(eventPelTerminate, levelPelError, additional);
164
165 // using system dbus, no reply
166 auto bus = sdbusplus::bus::new_system();
167 bus.call_noreply(method);
168 }
169 catch (const sdbusplus::exception::SdBusError& e)
170 {
austinfcuibfa831a2022-01-26 15:37:07 -0600171 trace::err("createPelRaw exception");
172 trace::err(e.what());
Ben Tyner188f1092021-02-01 09:33:06 -0600173 }
174 }
175}
176
177/** @brief Get file descriptor of exisitng PEL */
178int getPel(const uint32_t i_pelId)
179{
180 // GetPEL returns file descriptor (int)
181 int fd = -1;
182
183 // dbus specifics
184 constexpr auto interface = "org.open_power.Logging.PEL";
185 constexpr auto function = "GetPEL";
186
187 sdbusplus::message::message method;
188
189 if (0 == dbusMethod(pathLogging, interface, function, method))
190 {
191 try
192 {
193 // additional dbus call parameters
194 method.append(i_pelId);
195
196 // using system dbus
197 auto bus = sdbusplus::bus::new_system();
198 auto response = bus.call(method);
199
200 // reply will be a unix file descriptor
201 sdbusplus::message::unix_fd reply;
202
Ben Tyner4bbcb382021-02-22 09:29:00 -0600203 // parse dbus response into reply
Ben Tyner188f1092021-02-01 09:33:06 -0600204 response.read(reply);
205
206 fd = dup(reply); // need to copy (dup) the file descriptor
207 }
208 catch (const sdbusplus::exception::SdBusError& e)
209 {
austinfcuibfa831a2022-01-26 15:37:07 -0600210 trace::err("getPel exception");
211 trace::err(e.what());
Ben Tyner188f1092021-02-01 09:33:06 -0600212 }
213 }
214
215 return fd; // file descriptor or -1
216}
217
Ben Tyner188f1092021-02-01 09:33:06 -0600218} // namespace attn