blob: 21fae6fb4d16bc0feb923f36f86d91f6d5832cf7 [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 Tynera0982102022-02-16 14:19:41 -060015 sdbusplus::message::message& o_method)
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 Tynera0982102022-02-16 14:19:41 -060048 // return the method
49 o_method =
50 bus.new_method_call(service.c_str(), i_path.c_str(),
51 i_interface.c_str(), i_function.c_str());
Ben Tyner4bbcb382021-02-22 09:29:00 -060052 rc = RC_SUCCESS;
Ben Tyner188f1092021-02-01 09:33:06 -060053 }
54 else
55 {
Ben Tyner6764d702021-02-12 09:17:23 -060056 // This trace will be picked up in event log
austinfcuibfa831a2022-01-26 15:37:07 -060057 trace::inf("dbusMethod service not found");
58 trace::inf(i_path.c_str());
59 trace::inf(i_interface.c_str());
Ben Tyner188f1092021-02-01 09:33:06 -060060 }
61 }
62 catch (const sdbusplus::exception::SdBusError& e)
63 {
austinfcuibfa831a2022-01-26 15:37:07 -060064 trace::err("dbusMethod exception");
65 trace::err(e.what());
Ben Tyner188f1092021-02-01 09:33:06 -060066 }
67
68 return rc;
69}
70
71/** @brief Create a PEL for the specified event type */
72uint32_t createPel(const std::string& i_event,
73 std::map<std::string, std::string>& i_additional,
74 const std::vector<util::FFDCTuple>& i_ffdc)
75{
76 // CreatePELWithFFDCFiles returns plid
77 int plid = 0;
78
79 // Need to provide pid when using create or create-with-ffdc methods
80 i_additional.emplace("_PID", std::to_string(getpid()));
81
82 // Sdbus call specifics
83 constexpr auto interface = "org.open_power.Logging.PEL";
84 constexpr auto function = "CreatePELWithFFDCFiles";
85
86 sdbusplus::message::message method;
87
88 if (0 == dbusMethod(pathLogging, interface, function, method))
89 {
90 try
91 {
92 // append additional dbus call paramaters
93 method.append(i_event, levelPelError, i_additional, i_ffdc);
94
95 // using system dbus
96 auto bus = sdbusplus::bus::new_system();
97 auto response = bus.call(method);
98
99 // reply will be tuple containing bmc log id, platform log id
100 std::tuple<uint32_t, uint32_t> reply = {0, 0};
101
Ben Tyner4bbcb382021-02-22 09:29:00 -0600102 // parse dbus response into reply
Ben Tyner188f1092021-02-01 09:33:06 -0600103 response.read(reply);
104 plid = std::get<1>(reply); // platform log id is tuple "second"
105 }
106 catch (const sdbusplus::exception::SdBusError& e)
107 {
austinfcuibfa831a2022-01-26 15:37:07 -0600108 trace::err("createPel exception");
109 trace::err(e.what());
Ben Tyner188f1092021-02-01 09:33:06 -0600110 }
111 }
112
113 return plid; // platform log id or 0
114}
115
116/** @brief Create a PEL from raw PEL data */
117void createPelRaw(const std::vector<uint8_t>& i_buffer)
118{
119 // Create FFDC file from buffer data
120 util::FFDCFile pelFile{util::FFDCFormat::Text};
121 auto fd = pelFile.getFileDescriptor();
Ben Tyner188f1092021-02-01 09:33:06 -0600122
123 auto filePath = pelFile.getPath(); // path to ffdc file
124
Ben Tynerd7006092021-02-05 14:55:52 -0600125 size_t numBytes = write(fd, i_buffer.data(), i_buffer.size());
126 if (i_buffer.size() != numBytes)
127 {
austinfcuibfa831a2022-01-26 15:37:07 -0600128 trace::err("%s only %u of %u bytes written", filePath.c_str(), numBytes,
129 i_buffer.size());
Ben Tynerd7006092021-02-05 14:55:52 -0600130 }
131
132 lseek(fd, 0, SEEK_SET);
133
Ben Tyner188f1092021-02-01 09:33:06 -0600134 // Additional data for log
135 std::map<std::string, std::string> additional;
136 additional.emplace("RAWPEL", filePath.string());
137 additional.emplace("_PID", std::to_string(getpid()));
138
139 // dbus specifics
140 constexpr auto interface = "xyz.openbmc_project.Logging.Create";
141 constexpr auto function = "Create";
142
143 sdbusplus::message::message method;
144
145 if (0 == dbusMethod(pathLogging, interface, function, method))
146 {
147 try
148 {
149 // append additional dbus call parameters
150 method.append(eventPelTerminate, levelPelError, additional);
151
152 // using system dbus, no reply
153 auto bus = sdbusplus::bus::new_system();
154 bus.call_noreply(method);
155 }
156 catch (const sdbusplus::exception::SdBusError& e)
157 {
austinfcuibfa831a2022-01-26 15:37:07 -0600158 trace::err("createPelRaw exception");
159 trace::err(e.what());
Ben Tyner188f1092021-02-01 09:33:06 -0600160 }
161 }
162}
163
164/** @brief Get file descriptor of exisitng PEL */
165int getPel(const uint32_t i_pelId)
166{
167 // GetPEL returns file descriptor (int)
168 int fd = -1;
169
170 // dbus specifics
171 constexpr auto interface = "org.open_power.Logging.PEL";
172 constexpr auto function = "GetPEL";
173
174 sdbusplus::message::message method;
175
176 if (0 == dbusMethod(pathLogging, interface, function, method))
177 {
178 try
179 {
180 // additional dbus call parameters
181 method.append(i_pelId);
182
183 // using system dbus
184 auto bus = sdbusplus::bus::new_system();
185 auto response = bus.call(method);
186
187 // reply will be a unix file descriptor
188 sdbusplus::message::unix_fd reply;
189
Ben Tyner4bbcb382021-02-22 09:29:00 -0600190 // parse dbus response into reply
Ben Tyner188f1092021-02-01 09:33:06 -0600191 response.read(reply);
192
193 fd = dup(reply); // need to copy (dup) the file descriptor
194 }
195 catch (const sdbusplus::exception::SdBusError& e)
196 {
austinfcuibfa831a2022-01-26 15:37:07 -0600197 trace::err("getPel exception");
198 trace::err(e.what());
Ben Tyner188f1092021-02-01 09:33:06 -0600199 }
200 }
201
202 return fd; // file descriptor or -1
203}
204
Ben Tyner188f1092021-02-01 09:33:06 -0600205} // namespace attn