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