1 #include <attn/attn_common.hpp>
2 #include <attn/attn_dbus.hpp>
3 #include <attn/attn_logging.hpp>
4 #include <util/dbus.hpp>
5 #include <util/trace.hpp>
6
7 #include <string>
8 #include <vector>
9
10 namespace attn
11 {
12
13 /** @brief Create a dbus method */
dbusMethod(const std::string & i_path,const std::string & i_interface,const std::string & i_function,sdbusplus::message_t & o_method)14 int dbusMethod(const std::string& i_path, const std::string& i_interface,
15 const std::string& i_function, sdbusplus::message_t& o_method)
16 {
17 int rc = RC_DBUS_ERROR; // assume error
18
19 try
20 {
21 auto bus = sdbusplus::bus::new_system(); // using system dbus
22
23 // we need to find the service implementing the interface
24 util::dbus::DBusService service;
25
26 if (0 == util::dbus::findService(i_interface, i_path, service))
27 {
28 // return the method
29 o_method =
30 bus.new_method_call(service.c_str(), i_path.c_str(),
31 i_interface.c_str(), i_function.c_str());
32
33 rc = RC_SUCCESS;
34 }
35 else
36 {
37 // This trace will be picked up in event log
38 trace::inf("dbusMethod service not found");
39 trace::inf(i_path.c_str());
40 trace::inf(i_interface.c_str());
41 }
42 }
43 catch (const sdbusplus::exception::SdBusError& e)
44 {
45 trace::err("dbusMethod exception");
46 trace::err(e.what());
47 }
48
49 return rc;
50 }
51
52 /** @brief Create a PEL from raw PEL data */
createPelRaw(const std::vector<uint8_t> & i_buffer)53 void createPelRaw(const std::vector<uint8_t>& i_buffer)
54 {
55 // Create FFDC file from buffer data
56 util::FFDCFile pelFile{util::FFDCFormat::Text};
57 auto fd = pelFile.getFileDescriptor();
58
59 auto filePath = pelFile.getPath(); // path to ffdc file
60
61 size_t numBytes = write(fd, i_buffer.data(), i_buffer.size());
62 if (i_buffer.size() != numBytes)
63 {
64 trace::err("%s only %u of %u bytes written", filePath.c_str(), numBytes,
65 i_buffer.size());
66 }
67
68 lseek(fd, 0, SEEK_SET);
69
70 // Additional data for log
71 std::map<std::string, std::string> additional;
72 additional.emplace("RAWPEL", filePath.string());
73 additional.emplace("_PID", std::to_string(getpid()));
74
75 // dbus specifics
76 constexpr auto interface = "xyz.openbmc_project.Logging.Create";
77 constexpr auto function = "Create";
78
79 sdbusplus::message_t method;
80
81 if (0 == dbusMethod(pathLogging, interface, function, method))
82 {
83 try
84 {
85 // append additional dbus call parameters
86 method.append(eventPelTerminate, levelPelError, additional);
87
88 // using system dbus, no reply
89 auto bus = sdbusplus::bus::new_system();
90 bus.call_noreply(method);
91 }
92 catch (const sdbusplus::exception::SdBusError& e)
93 {
94 trace::err("createPelRaw exception");
95 trace::err(e.what());
96 }
97 }
98 }
99
100 /** @brief Get file descriptor of exisitng PEL */
getPel(const uint32_t i_pelId)101 int getPel(const uint32_t i_pelId)
102 {
103 // GetPEL returns file descriptor (int)
104 int fd = -1;
105
106 // dbus specifics
107 constexpr auto interface = "org.open_power.Logging.PEL";
108 constexpr auto function = "GetPEL";
109
110 sdbusplus::message_t method;
111
112 if (0 == dbusMethod(pathLogging, interface, function, method))
113 {
114 try
115 {
116 // additional dbus call parameters
117 method.append(i_pelId);
118
119 // using system dbus
120 auto bus = sdbusplus::bus::new_system();
121 auto response = bus.call(method);
122
123 // reply will be a unix file descriptor
124 sdbusplus::message::unix_fd reply;
125
126 // parse dbus response into reply
127 response.read(reply);
128
129 fd = dup(reply); // need to copy (dup) the file descriptor
130 }
131 catch (const sdbusplus::exception::SdBusError& e)
132 {
133 trace::err("getPel exception");
134 trace::err(e.what());
135 }
136 }
137
138 return fd; // file descriptor or -1
139 }
140
141 } // namespace attn
142