xref: /openbmc/openpower-hw-diags/attn/attn_dbus.cpp (revision a098210fc1ff08378b9643174534020cc6822ac3)
1f36466f4SZane Shelley #include <attn/attn_common.hpp>
2f36466f4SZane Shelley #include <attn/attn_dbus.hpp>
3f36466f4SZane Shelley #include <attn/attn_logging.hpp>
4bfa831a8Saustinfcui #include <util/trace.hpp>
5188f1096SBen Tyner 
6188f1096SBen Tyner #include <string>
7188f1096SBen Tyner #include <vector>
8188f1096SBen Tyner 
9188f1096SBen Tyner namespace attn
10188f1096SBen Tyner {
11188f1096SBen Tyner 
125c5db65aSBen Tyner /** @brief Create a dbus method */
13188f1096SBen Tyner int dbusMethod(const std::string& i_path, const std::string& i_interface,
14188f1096SBen Tyner                const std::string& i_function,
15*a098210fSBen Tyner                sdbusplus::message::message& o_method)
16188f1096SBen Tyner {
174bbcb38fSBen Tyner     int rc = RC_DBUS_ERROR; // assume error
18188f1096SBen Tyner 
19188f1096SBen Tyner     try
20188f1096SBen Tyner     {
21188f1096SBen Tyner         constexpr auto serviceFind   = "xyz.openbmc_project.ObjectMapper";
22188f1096SBen Tyner         constexpr auto pathFind      = "/xyz/openbmc_project/object_mapper";
23188f1096SBen Tyner         constexpr auto interfaceFind = "xyz.openbmc_project.ObjectMapper";
24188f1096SBen Tyner         constexpr auto functionFind  = "GetObject";
25188f1096SBen Tyner 
26188f1096SBen Tyner         auto bus = sdbusplus::bus::new_system(); // using system dbus
27188f1096SBen Tyner 
28188f1096SBen Tyner         // method to find service from object path and object interface
29188f1096SBen Tyner         auto method = bus.new_method_call(serviceFind, pathFind, interfaceFind,
30188f1096SBen Tyner                                           functionFind);
31188f1096SBen Tyner 
32188f1096SBen Tyner         // find the service for specified object path and interface
33188f1096SBen Tyner         method.append(i_path.c_str());
34188f1096SBen Tyner         method.append(std::vector<std::string>({i_interface}));
35188f1096SBen Tyner         auto reply = bus.call(method);
36188f1096SBen Tyner 
37188f1096SBen Tyner         // dbus call results
38188f1096SBen Tyner         std::map<std::string, std::vector<std::string>> responseFindService;
39188f1096SBen Tyner         reply.read(responseFindService);
40188f1096SBen Tyner 
41188f1096SBen Tyner         // If we successfully found the service associated with the dbus object
42188f1096SBen Tyner         // path and interface then create a method for the specified interface
43188f1096SBen Tyner         // and function.
44188f1096SBen Tyner         if (!responseFindService.empty())
45188f1096SBen Tyner         {
46188f1096SBen Tyner             auto service = responseFindService.begin()->first;
47188f1096SBen Tyner 
48188f1096SBen Tyner             // return the method
49188f1096SBen Tyner             o_method =
50188f1096SBen Tyner                 bus.new_method_call(service.c_str(), i_path.c_str(),
51*a098210fSBen Tyner                                     i_interface.c_str(), i_function.c_str());
524bbcb38fSBen Tyner             rc = RC_SUCCESS;
53188f1096SBen Tyner         }
54188f1096SBen Tyner         else
55188f1096SBen Tyner         {
566764d70eSBen Tyner             // This trace will be picked up in event log
57bfa831a8Saustinfcui             trace::inf("dbusMethod service not found");
58bfa831a8Saustinfcui             trace::inf(i_path.c_str());
59bfa831a8Saustinfcui             trace::inf(i_interface.c_str());
60188f1096SBen Tyner         }
61188f1096SBen Tyner     }
62188f1096SBen Tyner     catch (const sdbusplus::exception::SdBusError& e)
63188f1096SBen Tyner     {
64bfa831a8Saustinfcui         trace::err("dbusMethod exception");
65bfa831a8Saustinfcui         trace::err(e.what());
66188f1096SBen Tyner     }
67188f1096SBen Tyner 
68188f1096SBen Tyner     return rc;
69188f1096SBen Tyner }
70188f1096SBen Tyner 
71188f1096SBen Tyner /** @brief Create a PEL for the specified event type */
72188f1096SBen Tyner uint32_t createPel(const std::string& i_event,
73188f1096SBen Tyner                    std::map<std::string, std::string>& i_additional,
74188f1096SBen Tyner                    const std::vector<util::FFDCTuple>& i_ffdc)
75188f1096SBen Tyner {
76188f1096SBen Tyner     // CreatePELWithFFDCFiles returns plid
77188f1096SBen Tyner     int plid = 0;
78188f1096SBen Tyner 
79188f1096SBen Tyner     // Need to provide pid when using create or create-with-ffdc methods
80188f1096SBen Tyner     i_additional.emplace("_PID", std::to_string(getpid()));
81188f1096SBen Tyner 
82188f1096SBen Tyner     // Sdbus call specifics
83188f1096SBen Tyner     constexpr auto interface = "org.open_power.Logging.PEL";
84188f1096SBen Tyner     constexpr auto function  = "CreatePELWithFFDCFiles";
85188f1096SBen Tyner 
86188f1096SBen Tyner     sdbusplus::message::message method;
87188f1096SBen Tyner 
88188f1096SBen Tyner     if (0 == dbusMethod(pathLogging, interface, function, method))
89188f1096SBen Tyner     {
90188f1096SBen Tyner         try
91188f1096SBen Tyner         {
92188f1096SBen Tyner             // append additional dbus call paramaters
93188f1096SBen Tyner             method.append(i_event, levelPelError, i_additional, i_ffdc);
94188f1096SBen Tyner 
95188f1096SBen Tyner             // using system dbus
96188f1096SBen Tyner             auto bus      = sdbusplus::bus::new_system();
97188f1096SBen Tyner             auto response = bus.call(method);
98188f1096SBen Tyner 
99188f1096SBen Tyner             // reply will be tuple containing bmc log id, platform log id
100188f1096SBen Tyner             std::tuple<uint32_t, uint32_t> reply = {0, 0};
101188f1096SBen Tyner 
1024bbcb38fSBen Tyner             // parse dbus response into reply
103188f1096SBen Tyner             response.read(reply);
104188f1096SBen Tyner             plid = std::get<1>(reply); // platform log id is tuple "second"
105188f1096SBen Tyner         }
106188f1096SBen Tyner         catch (const sdbusplus::exception::SdBusError& e)
107188f1096SBen Tyner         {
108bfa831a8Saustinfcui             trace::err("createPel exception");
109bfa831a8Saustinfcui             trace::err(e.what());
110188f1096SBen Tyner         }
111188f1096SBen Tyner     }
112188f1096SBen Tyner 
113188f1096SBen Tyner     return plid; // platform log id or 0
114188f1096SBen Tyner }
115188f1096SBen Tyner 
116188f1096SBen Tyner /** @brief Create a PEL from raw PEL data */
117188f1096SBen Tyner void createPelRaw(const std::vector<uint8_t>& i_buffer)
118188f1096SBen Tyner {
119188f1096SBen Tyner     // Create FFDC file from buffer data
120188f1096SBen Tyner     util::FFDCFile pelFile{util::FFDCFormat::Text};
121188f1096SBen Tyner     auto fd = pelFile.getFileDescriptor();
122188f1096SBen Tyner 
123188f1096SBen Tyner     auto filePath = pelFile.getPath(); // path to ffdc file
124188f1096SBen Tyner 
125d700609cSBen Tyner     size_t numBytes = write(fd, i_buffer.data(), i_buffer.size());
126d700609cSBen Tyner     if (i_buffer.size() != numBytes)
127d700609cSBen Tyner     {
128bfa831a8Saustinfcui         trace::err("%s only %u of %u bytes written", filePath.c_str(), numBytes,
129bfa831a8Saustinfcui                    i_buffer.size());
130d700609cSBen Tyner     }
131d700609cSBen Tyner 
132d700609cSBen Tyner     lseek(fd, 0, SEEK_SET);
133d700609cSBen Tyner 
134188f1096SBen Tyner     // Additional data for log
135188f1096SBen Tyner     std::map<std::string, std::string> additional;
136188f1096SBen Tyner     additional.emplace("RAWPEL", filePath.string());
137188f1096SBen Tyner     additional.emplace("_PID", std::to_string(getpid()));
138188f1096SBen Tyner 
139188f1096SBen Tyner     // dbus specifics
140188f1096SBen Tyner     constexpr auto interface = "xyz.openbmc_project.Logging.Create";
141188f1096SBen Tyner     constexpr auto function  = "Create";
142188f1096SBen Tyner 
143188f1096SBen Tyner     sdbusplus::message::message method;
144188f1096SBen Tyner 
145188f1096SBen Tyner     if (0 == dbusMethod(pathLogging, interface, function, method))
146188f1096SBen Tyner     {
147188f1096SBen Tyner         try
148188f1096SBen Tyner         {
149188f1096SBen Tyner             // append additional dbus call parameters
150188f1096SBen Tyner             method.append(eventPelTerminate, levelPelError, additional);
151188f1096SBen Tyner 
152188f1096SBen Tyner             // using system dbus, no reply
153188f1096SBen Tyner             auto bus = sdbusplus::bus::new_system();
154188f1096SBen Tyner             bus.call_noreply(method);
155188f1096SBen Tyner         }
156188f1096SBen Tyner         catch (const sdbusplus::exception::SdBusError& e)
157188f1096SBen Tyner         {
158bfa831a8Saustinfcui             trace::err("createPelRaw exception");
159bfa831a8Saustinfcui             trace::err(e.what());
160188f1096SBen Tyner         }
161188f1096SBen Tyner     }
162188f1096SBen Tyner }
163188f1096SBen Tyner 
164188f1096SBen Tyner /** @brief Get file descriptor of exisitng PEL */
165188f1096SBen Tyner int getPel(const uint32_t i_pelId)
166188f1096SBen Tyner {
167188f1096SBen Tyner     // GetPEL returns file descriptor (int)
168188f1096SBen Tyner     int fd = -1;
169188f1096SBen Tyner 
170188f1096SBen Tyner     // dbus specifics
171188f1096SBen Tyner     constexpr auto interface = "org.open_power.Logging.PEL";
172188f1096SBen Tyner     constexpr auto function  = "GetPEL";
173188f1096SBen Tyner 
174188f1096SBen Tyner     sdbusplus::message::message method;
175188f1096SBen Tyner 
176188f1096SBen Tyner     if (0 == dbusMethod(pathLogging, interface, function, method))
177188f1096SBen Tyner     {
178188f1096SBen Tyner         try
179188f1096SBen Tyner         {
180188f1096SBen Tyner             // additional dbus call parameters
181188f1096SBen Tyner             method.append(i_pelId);
182188f1096SBen Tyner 
183188f1096SBen Tyner             // using system dbus
184188f1096SBen Tyner             auto bus      = sdbusplus::bus::new_system();
185188f1096SBen Tyner             auto response = bus.call(method);
186188f1096SBen Tyner 
187188f1096SBen Tyner             // reply will be a unix file descriptor
188188f1096SBen Tyner             sdbusplus::message::unix_fd reply;
189188f1096SBen Tyner 
1904bbcb38fSBen Tyner             // parse dbus response into reply
191188f1096SBen Tyner             response.read(reply);
192188f1096SBen Tyner 
193188f1096SBen Tyner             fd = dup(reply); // need to copy (dup) the file descriptor
194188f1096SBen Tyner         }
195188f1096SBen Tyner         catch (const sdbusplus::exception::SdBusError& e)
196188f1096SBen Tyner         {
197bfa831a8Saustinfcui             trace::err("getPel exception");
198bfa831a8Saustinfcui             trace::err(e.what());
199188f1096SBen Tyner         }
200188f1096SBen Tyner     }
201188f1096SBen Tyner 
202188f1096SBen Tyner     return fd; // file descriptor or -1
203188f1096SBen Tyner }
204188f1096SBen Tyner 
205188f1096SBen Tyner } // namespace attn
206