xref: /openbmc/openpower-hw-diags/attn/attn_dbus.cpp (revision 42260bc33a33ba21e50d132e996268bba33108fd)
1f36466f4SZane Shelley #include <attn/attn_common.hpp>
2f36466f4SZane Shelley #include <attn/attn_dbus.hpp>
3f36466f4SZane Shelley #include <attn/attn_logging.hpp>
4*42260bc3SBen Tyner #include <util/dbus.hpp>
5bfa831a8Saustinfcui #include <util/trace.hpp>
6188f1096SBen Tyner 
7188f1096SBen Tyner #include <string>
8188f1096SBen Tyner #include <vector>
9188f1096SBen Tyner 
10188f1096SBen Tyner namespace attn
11188f1096SBen Tyner {
12188f1096SBen Tyner 
135c5db65aSBen Tyner /** @brief Create a dbus method */
14188f1096SBen Tyner int dbusMethod(const std::string& i_path, const std::string& i_interface,
15188f1096SBen Tyner                const std::string& i_function,
16a098210fSBen Tyner                sdbusplus::message::message& o_method)
17188f1096SBen Tyner {
184bbcb38fSBen Tyner     int rc = RC_DBUS_ERROR; // assume error
19188f1096SBen Tyner 
20188f1096SBen Tyner     try
21188f1096SBen Tyner     {
22188f1096SBen Tyner         auto bus = sdbusplus::bus::new_system(); // using system dbus
23188f1096SBen Tyner 
24*42260bc3SBen Tyner         // we need to find the service implementing the interface
25*42260bc3SBen Tyner         util::dbus::DBusService service;
26188f1096SBen Tyner 
27*42260bc3SBen Tyner         if (0 == util::dbus::findService(i_interface, i_path, service))
28188f1096SBen Tyner         {
29188f1096SBen Tyner             // return the method
30188f1096SBen Tyner             o_method =
31188f1096SBen Tyner                 bus.new_method_call(service.c_str(), i_path.c_str(),
32a098210fSBen Tyner                                     i_interface.c_str(), i_function.c_str());
33*42260bc3SBen Tyner 
344bbcb38fSBen Tyner             rc = RC_SUCCESS;
35188f1096SBen Tyner         }
36188f1096SBen Tyner         else
37188f1096SBen Tyner         {
386764d70eSBen Tyner             // This trace will be picked up in event log
39bfa831a8Saustinfcui             trace::inf("dbusMethod service not found");
40bfa831a8Saustinfcui             trace::inf(i_path.c_str());
41bfa831a8Saustinfcui             trace::inf(i_interface.c_str());
42188f1096SBen Tyner         }
43188f1096SBen Tyner     }
44188f1096SBen Tyner     catch (const sdbusplus::exception::SdBusError& e)
45188f1096SBen Tyner     {
46bfa831a8Saustinfcui         trace::err("dbusMethod exception");
47bfa831a8Saustinfcui         trace::err(e.what());
48188f1096SBen Tyner     }
49188f1096SBen Tyner 
50188f1096SBen Tyner     return rc;
51188f1096SBen Tyner }
52188f1096SBen Tyner 
53188f1096SBen Tyner /** @brief Create a PEL for the specified event type */
54188f1096SBen Tyner uint32_t createPel(const std::string& i_event,
55188f1096SBen Tyner                    std::map<std::string, std::string>& i_additional,
56188f1096SBen Tyner                    const std::vector<util::FFDCTuple>& i_ffdc)
57188f1096SBen Tyner {
58188f1096SBen Tyner     // CreatePELWithFFDCFiles returns plid
59188f1096SBen Tyner     int plid = 0;
60188f1096SBen Tyner 
61188f1096SBen Tyner     // Need to provide pid when using create or create-with-ffdc methods
62188f1096SBen Tyner     i_additional.emplace("_PID", std::to_string(getpid()));
63188f1096SBen Tyner 
64188f1096SBen Tyner     // Sdbus call specifics
65188f1096SBen Tyner     constexpr auto interface = "org.open_power.Logging.PEL";
66188f1096SBen Tyner     constexpr auto function  = "CreatePELWithFFDCFiles";
67188f1096SBen Tyner 
68188f1096SBen Tyner     sdbusplus::message::message method;
69188f1096SBen Tyner 
70188f1096SBen Tyner     if (0 == dbusMethod(pathLogging, interface, function, method))
71188f1096SBen Tyner     {
72188f1096SBen Tyner         try
73188f1096SBen Tyner         {
74188f1096SBen Tyner             // append additional dbus call paramaters
75188f1096SBen Tyner             method.append(i_event, levelPelError, i_additional, i_ffdc);
76188f1096SBen Tyner 
77188f1096SBen Tyner             // using system dbus
78188f1096SBen Tyner             auto bus      = sdbusplus::bus::new_system();
79188f1096SBen Tyner             auto response = bus.call(method);
80188f1096SBen Tyner 
81188f1096SBen Tyner             // reply will be tuple containing bmc log id, platform log id
82188f1096SBen Tyner             std::tuple<uint32_t, uint32_t> reply = {0, 0};
83188f1096SBen Tyner 
844bbcb38fSBen Tyner             // parse dbus response into reply
85188f1096SBen Tyner             response.read(reply);
86188f1096SBen Tyner             plid = std::get<1>(reply); // platform log id is tuple "second"
87188f1096SBen Tyner         }
88188f1096SBen Tyner         catch (const sdbusplus::exception::SdBusError& e)
89188f1096SBen Tyner         {
90bfa831a8Saustinfcui             trace::err("createPel exception");
91bfa831a8Saustinfcui             trace::err(e.what());
92188f1096SBen Tyner         }
93188f1096SBen Tyner     }
94188f1096SBen Tyner 
95188f1096SBen Tyner     return plid; // platform log id or 0
96188f1096SBen Tyner }
97188f1096SBen Tyner 
98188f1096SBen Tyner /** @brief Create a PEL from raw PEL data */
99188f1096SBen Tyner void createPelRaw(const std::vector<uint8_t>& i_buffer)
100188f1096SBen Tyner {
101188f1096SBen Tyner     // Create FFDC file from buffer data
102188f1096SBen Tyner     util::FFDCFile pelFile{util::FFDCFormat::Text};
103188f1096SBen Tyner     auto fd = pelFile.getFileDescriptor();
104188f1096SBen Tyner 
105188f1096SBen Tyner     auto filePath = pelFile.getPath(); // path to ffdc file
106188f1096SBen Tyner 
107d700609cSBen Tyner     size_t numBytes = write(fd, i_buffer.data(), i_buffer.size());
108d700609cSBen Tyner     if (i_buffer.size() != numBytes)
109d700609cSBen Tyner     {
110bfa831a8Saustinfcui         trace::err("%s only %u of %u bytes written", filePath.c_str(), numBytes,
111bfa831a8Saustinfcui                    i_buffer.size());
112d700609cSBen Tyner     }
113d700609cSBen Tyner 
114d700609cSBen Tyner     lseek(fd, 0, SEEK_SET);
115d700609cSBen Tyner 
116188f1096SBen Tyner     // Additional data for log
117188f1096SBen Tyner     std::map<std::string, std::string> additional;
118188f1096SBen Tyner     additional.emplace("RAWPEL", filePath.string());
119188f1096SBen Tyner     additional.emplace("_PID", std::to_string(getpid()));
120188f1096SBen Tyner 
121188f1096SBen Tyner     // dbus specifics
122188f1096SBen Tyner     constexpr auto interface = "xyz.openbmc_project.Logging.Create";
123188f1096SBen Tyner     constexpr auto function  = "Create";
124188f1096SBen Tyner 
125188f1096SBen Tyner     sdbusplus::message::message method;
126188f1096SBen Tyner 
127188f1096SBen Tyner     if (0 == dbusMethod(pathLogging, interface, function, method))
128188f1096SBen Tyner     {
129188f1096SBen Tyner         try
130188f1096SBen Tyner         {
131188f1096SBen Tyner             // append additional dbus call parameters
132188f1096SBen Tyner             method.append(eventPelTerminate, levelPelError, additional);
133188f1096SBen Tyner 
134188f1096SBen Tyner             // using system dbus, no reply
135188f1096SBen Tyner             auto bus = sdbusplus::bus::new_system();
136188f1096SBen Tyner             bus.call_noreply(method);
137188f1096SBen Tyner         }
138188f1096SBen Tyner         catch (const sdbusplus::exception::SdBusError& e)
139188f1096SBen Tyner         {
140bfa831a8Saustinfcui             trace::err("createPelRaw exception");
141bfa831a8Saustinfcui             trace::err(e.what());
142188f1096SBen Tyner         }
143188f1096SBen Tyner     }
144188f1096SBen Tyner }
145188f1096SBen Tyner 
146188f1096SBen Tyner /** @brief Get file descriptor of exisitng PEL */
147188f1096SBen Tyner int getPel(const uint32_t i_pelId)
148188f1096SBen Tyner {
149188f1096SBen Tyner     // GetPEL returns file descriptor (int)
150188f1096SBen Tyner     int fd = -1;
151188f1096SBen Tyner 
152188f1096SBen Tyner     // dbus specifics
153188f1096SBen Tyner     constexpr auto interface = "org.open_power.Logging.PEL";
154188f1096SBen Tyner     constexpr auto function  = "GetPEL";
155188f1096SBen Tyner 
156188f1096SBen Tyner     sdbusplus::message::message method;
157188f1096SBen Tyner 
158188f1096SBen Tyner     if (0 == dbusMethod(pathLogging, interface, function, method))
159188f1096SBen Tyner     {
160188f1096SBen Tyner         try
161188f1096SBen Tyner         {
162188f1096SBen Tyner             // additional dbus call parameters
163188f1096SBen Tyner             method.append(i_pelId);
164188f1096SBen Tyner 
165188f1096SBen Tyner             // using system dbus
166188f1096SBen Tyner             auto bus      = sdbusplus::bus::new_system();
167188f1096SBen Tyner             auto response = bus.call(method);
168188f1096SBen Tyner 
169188f1096SBen Tyner             // reply will be a unix file descriptor
170188f1096SBen Tyner             sdbusplus::message::unix_fd reply;
171188f1096SBen Tyner 
1724bbcb38fSBen Tyner             // parse dbus response into reply
173188f1096SBen Tyner             response.read(reply);
174188f1096SBen Tyner 
175188f1096SBen Tyner             fd = dup(reply); // need to copy (dup) the file descriptor
176188f1096SBen Tyner         }
177188f1096SBen Tyner         catch (const sdbusplus::exception::SdBusError& e)
178188f1096SBen Tyner         {
179bfa831a8Saustinfcui             trace::err("getPel exception");
180bfa831a8Saustinfcui             trace::err(e.what());
181188f1096SBen Tyner         }
182188f1096SBen Tyner     }
183188f1096SBen Tyner 
184188f1096SBen Tyner     return fd; // file descriptor or -1
185188f1096SBen Tyner }
186188f1096SBen Tyner 
187188f1096SBen Tyner } // namespace attn
188