blob: e4ad47ad670632fb9ffc56a610b6581f27970a73 [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>
Ben Tyner42260bc2022-02-16 14:36:58 -06004#include <util/dbus.hpp>
austinfcuibfa831a2022-01-26 15:37:07 -06005#include <util/trace.hpp>
Ben Tyner188f1092021-02-01 09:33:06 -06006
7#include <string>
8#include <vector>
9
10namespace attn
11{
12
Ben Tyner5c5db652021-02-22 18:22:35 -060013/** @brief Create a dbus method */
Ben Tyner188f1092021-02-01 09:33:06 -060014int dbusMethod(const std::string& i_path, const std::string& i_interface,
15 const std::string& i_function,
Ben Tynera0982102022-02-16 14:19:41 -060016 sdbusplus::message::message& o_method)
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 {
Ben Tyner188f1092021-02-01 09:33:06 -060022 auto bus = sdbusplus::bus::new_system(); // using system dbus
23
Ben Tyner42260bc2022-02-16 14:36:58 -060024 // we need to find the service implementing the interface
25 util::dbus::DBusService service;
Ben Tyner188f1092021-02-01 09:33:06 -060026
Ben Tyner42260bc2022-02-16 14:36:58 -060027 if (0 == util::dbus::findService(i_interface, i_path, service))
Ben Tyner188f1092021-02-01 09:33:06 -060028 {
Ben Tynera0982102022-02-16 14:19:41 -060029 // return the method
30 o_method =
31 bus.new_method_call(service.c_str(), i_path.c_str(),
32 i_interface.c_str(), i_function.c_str());
Ben Tyner42260bc2022-02-16 14:36:58 -060033
Ben Tyner4bbcb382021-02-22 09:29:00 -060034 rc = RC_SUCCESS;
Ben Tyner188f1092021-02-01 09:33:06 -060035 }
36 else
37 {
Ben Tyner6764d702021-02-12 09:17:23 -060038 // This trace will be picked up in event log
austinfcuibfa831a2022-01-26 15:37:07 -060039 trace::inf("dbusMethod service not found");
40 trace::inf(i_path.c_str());
41 trace::inf(i_interface.c_str());
Ben Tyner188f1092021-02-01 09:33:06 -060042 }
43 }
44 catch (const sdbusplus::exception::SdBusError& e)
45 {
austinfcuibfa831a2022-01-26 15:37:07 -060046 trace::err("dbusMethod exception");
47 trace::err(e.what());
Ben Tyner188f1092021-02-01 09:33:06 -060048 }
49
50 return rc;
51}
52
53/** @brief Create a PEL for the specified event type */
54uint32_t createPel(const std::string& i_event,
55 std::map<std::string, std::string>& i_additional,
56 const std::vector<util::FFDCTuple>& i_ffdc)
57{
58 // CreatePELWithFFDCFiles returns plid
59 int plid = 0;
60
61 // Need to provide pid when using create or create-with-ffdc methods
62 i_additional.emplace("_PID", std::to_string(getpid()));
63
64 // Sdbus call specifics
65 constexpr auto interface = "org.open_power.Logging.PEL";
66 constexpr auto function = "CreatePELWithFFDCFiles";
67
68 sdbusplus::message::message method;
69
70 if (0 == dbusMethod(pathLogging, interface, function, method))
71 {
72 try
73 {
74 // append additional dbus call paramaters
75 method.append(i_event, levelPelError, i_additional, i_ffdc);
76
77 // using system dbus
78 auto bus = sdbusplus::bus::new_system();
79 auto response = bus.call(method);
80
81 // reply will be tuple containing bmc log id, platform log id
82 std::tuple<uint32_t, uint32_t> reply = {0, 0};
83
Ben Tyner4bbcb382021-02-22 09:29:00 -060084 // parse dbus response into reply
Ben Tyner188f1092021-02-01 09:33:06 -060085 response.read(reply);
86 plid = std::get<1>(reply); // platform log id is tuple "second"
87 }
88 catch (const sdbusplus::exception::SdBusError& e)
89 {
austinfcuibfa831a2022-01-26 15:37:07 -060090 trace::err("createPel exception");
91 trace::err(e.what());
Ben Tyner188f1092021-02-01 09:33:06 -060092 }
93 }
94
95 return plid; // platform log id or 0
96}
97
98/** @brief Create a PEL from raw PEL data */
99void createPelRaw(const std::vector<uint8_t>& i_buffer)
100{
101 // Create FFDC file from buffer data
102 util::FFDCFile pelFile{util::FFDCFormat::Text};
103 auto fd = pelFile.getFileDescriptor();
Ben Tyner188f1092021-02-01 09:33:06 -0600104
105 auto filePath = pelFile.getPath(); // path to ffdc file
106
Ben Tynerd7006092021-02-05 14:55:52 -0600107 size_t numBytes = write(fd, i_buffer.data(), i_buffer.size());
108 if (i_buffer.size() != numBytes)
109 {
austinfcuibfa831a2022-01-26 15:37:07 -0600110 trace::err("%s only %u of %u bytes written", filePath.c_str(), numBytes,
111 i_buffer.size());
Ben Tynerd7006092021-02-05 14:55:52 -0600112 }
113
114 lseek(fd, 0, SEEK_SET);
115
Ben Tyner188f1092021-02-01 09:33:06 -0600116 // Additional data for log
117 std::map<std::string, std::string> additional;
118 additional.emplace("RAWPEL", filePath.string());
119 additional.emplace("_PID", std::to_string(getpid()));
120
121 // dbus specifics
122 constexpr auto interface = "xyz.openbmc_project.Logging.Create";
123 constexpr auto function = "Create";
124
125 sdbusplus::message::message method;
126
127 if (0 == dbusMethod(pathLogging, interface, function, method))
128 {
129 try
130 {
131 // append additional dbus call parameters
132 method.append(eventPelTerminate, levelPelError, additional);
133
134 // using system dbus, no reply
135 auto bus = sdbusplus::bus::new_system();
136 bus.call_noreply(method);
137 }
138 catch (const sdbusplus::exception::SdBusError& e)
139 {
austinfcuibfa831a2022-01-26 15:37:07 -0600140 trace::err("createPelRaw exception");
141 trace::err(e.what());
Ben Tyner188f1092021-02-01 09:33:06 -0600142 }
143 }
144}
145
146/** @brief Get file descriptor of exisitng PEL */
147int getPel(const uint32_t i_pelId)
148{
149 // GetPEL returns file descriptor (int)
150 int fd = -1;
151
152 // dbus specifics
153 constexpr auto interface = "org.open_power.Logging.PEL";
154 constexpr auto function = "GetPEL";
155
156 sdbusplus::message::message method;
157
158 if (0 == dbusMethod(pathLogging, interface, function, method))
159 {
160 try
161 {
162 // additional dbus call parameters
163 method.append(i_pelId);
164
165 // using system dbus
166 auto bus = sdbusplus::bus::new_system();
167 auto response = bus.call(method);
168
169 // reply will be a unix file descriptor
170 sdbusplus::message::unix_fd reply;
171
Ben Tyner4bbcb382021-02-22 09:29:00 -0600172 // parse dbus response into reply
Ben Tyner188f1092021-02-01 09:33:06 -0600173 response.read(reply);
174
175 fd = dup(reply); // need to copy (dup) the file descriptor
176 }
177 catch (const sdbusplus::exception::SdBusError& e)
178 {
austinfcuibfa831a2022-01-26 15:37:07 -0600179 trace::err("getPel exception");
180 trace::err(e.what());
Ben Tyner188f1092021-02-01 09:33:06 -0600181 }
182 }
183
184 return fd; // file descriptor or -1
185}
186
Ben Tyner188f1092021-02-01 09:33:06 -0600187} // namespace attn