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 */ 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 */ 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 */ 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