1188f1096SBen Tyner #include <attn_logging.hpp> 2188f1096SBen Tyner 3188f1096SBen Tyner #include <string> 4188f1096SBen Tyner #include <vector> 5188f1096SBen Tyner 6188f1096SBen Tyner namespace attn 7188f1096SBen Tyner { 8188f1096SBen Tyner 9188f1096SBen Tyner /** 10188f1096SBen Tyner * Create a dbus method 11188f1096SBen Tyner * 12188f1096SBen Tyner * Find the dbus service associated with the dbus object path and create 13188f1096SBen Tyner * a dbus method for calling the specified dbus interface and function. 14188f1096SBen Tyner * 15188f1096SBen Tyner * @param i_path - dbus object path 16188f1096SBen Tyner * @param i_interface - dbus method interface 17188f1096SBen Tyner * @param i_function - dbus interface function 18188f1096SBen Tyner * @param o_method - method that is created 19188f1096SBen Tyner * @return non-zero if error 20188f1096SBen Tyner * 21188f1096SBen Tyner **/ 22188f1096SBen Tyner int dbusMethod(const std::string& i_path, const std::string& i_interface, 23188f1096SBen Tyner const std::string& i_function, 24188f1096SBen Tyner sdbusplus::message::message& o_method) 25188f1096SBen Tyner { 26188f1096SBen Tyner int rc = 1; // assume error 27188f1096SBen Tyner 28188f1096SBen Tyner try 29188f1096SBen Tyner { 30188f1096SBen Tyner constexpr auto serviceFind = "xyz.openbmc_project.ObjectMapper"; 31188f1096SBen Tyner constexpr auto pathFind = "/xyz/openbmc_project/object_mapper"; 32188f1096SBen Tyner constexpr auto interfaceFind = "xyz.openbmc_project.ObjectMapper"; 33188f1096SBen Tyner constexpr auto functionFind = "GetObject"; 34188f1096SBen Tyner 35188f1096SBen Tyner auto bus = sdbusplus::bus::new_system(); // using system dbus 36188f1096SBen Tyner 37188f1096SBen Tyner // method to find service from object path and object interface 38188f1096SBen Tyner auto method = bus.new_method_call(serviceFind, pathFind, interfaceFind, 39188f1096SBen Tyner functionFind); 40188f1096SBen Tyner 41188f1096SBen Tyner // find the service for specified object path and interface 42188f1096SBen Tyner method.append(i_path.c_str()); 43188f1096SBen Tyner method.append(std::vector<std::string>({i_interface})); 44188f1096SBen Tyner auto reply = bus.call(method); 45188f1096SBen Tyner 46188f1096SBen Tyner // dbus call results 47188f1096SBen Tyner std::map<std::string, std::vector<std::string>> responseFindService; 48188f1096SBen Tyner reply.read(responseFindService); 49188f1096SBen Tyner 50188f1096SBen Tyner // If we successfully found the service associated with the dbus object 51188f1096SBen Tyner // path and interface then create a method for the specified interface 52188f1096SBen Tyner // and function. 53188f1096SBen Tyner if (!responseFindService.empty()) 54188f1096SBen Tyner { 55188f1096SBen Tyner auto service = responseFindService.begin()->first; 56188f1096SBen Tyner 57188f1096SBen Tyner // return the method 58188f1096SBen Tyner o_method = 59188f1096SBen Tyner bus.new_method_call(service.c_str(), i_path.c_str(), 60188f1096SBen Tyner i_interface.c_str(), i_function.c_str()); 61188f1096SBen Tyner 62188f1096SBen Tyner rc = 0; 63188f1096SBen Tyner } 64188f1096SBen Tyner else 65188f1096SBen Tyner { 66188f1096SBen Tyner std::stringstream ss; 67188f1096SBen Tyner ss << "dbusMethod service not found: " << i_path.c_str() << ", " 68188f1096SBen Tyner << i_interface.c_str(); 69188f1096SBen Tyner trace<level::INFO>(ss.str().c_str()); 70188f1096SBen Tyner } 71188f1096SBen Tyner } 72188f1096SBen Tyner catch (const sdbusplus::exception::SdBusError& e) 73188f1096SBen Tyner { 74188f1096SBen Tyner std::stringstream ss; 75188f1096SBen Tyner ss << "dbusMethod exception: " << e.what(); 76188f1096SBen Tyner trace<level::INFO>(ss.str().c_str()); 77188f1096SBen Tyner } 78188f1096SBen Tyner 79188f1096SBen Tyner return rc; 80188f1096SBen Tyner } 81188f1096SBen Tyner 82188f1096SBen Tyner /** @brief Create a PEL for the specified event type */ 83188f1096SBen Tyner uint32_t createPel(const std::string& i_event, 84188f1096SBen Tyner std::map<std::string, std::string>& i_additional, 85188f1096SBen Tyner const std::vector<util::FFDCTuple>& i_ffdc) 86188f1096SBen Tyner { 87188f1096SBen Tyner // CreatePELWithFFDCFiles returns plid 88188f1096SBen Tyner int plid = 0; 89188f1096SBen Tyner 90188f1096SBen Tyner // Need to provide pid when using create or create-with-ffdc methods 91188f1096SBen Tyner i_additional.emplace("_PID", std::to_string(getpid())); 92188f1096SBen Tyner 93188f1096SBen Tyner // Sdbus call specifics 94188f1096SBen Tyner constexpr auto interface = "org.open_power.Logging.PEL"; 95188f1096SBen Tyner constexpr auto function = "CreatePELWithFFDCFiles"; 96188f1096SBen Tyner 97188f1096SBen Tyner sdbusplus::message::message method; 98188f1096SBen Tyner 99188f1096SBen Tyner if (0 == dbusMethod(pathLogging, interface, function, method)) 100188f1096SBen Tyner { 101188f1096SBen Tyner try 102188f1096SBen Tyner { 103188f1096SBen Tyner // append additional dbus call paramaters 104188f1096SBen Tyner method.append(i_event, levelPelError, i_additional, i_ffdc); 105188f1096SBen Tyner 106188f1096SBen Tyner // using system dbus 107188f1096SBen Tyner auto bus = sdbusplus::bus::new_system(); 108188f1096SBen Tyner auto response = bus.call(method); 109188f1096SBen Tyner 110188f1096SBen Tyner // reply will be tuple containing bmc log id, platform log id 111188f1096SBen Tyner std::tuple<uint32_t, uint32_t> reply = {0, 0}; 112188f1096SBen Tyner 113188f1096SBen Tyner // parse dbus reply 114188f1096SBen Tyner response.read(reply); 115188f1096SBen Tyner plid = std::get<1>(reply); // platform log id is tuple "second" 116188f1096SBen Tyner } 117188f1096SBen Tyner catch (const sdbusplus::exception::SdBusError& e) 118188f1096SBen Tyner { 119188f1096SBen Tyner std::stringstream ss; 120188f1096SBen Tyner ss << "createPel exception: " << e.what(); 121188f1096SBen Tyner trace<level::INFO>(ss.str().c_str()); 122188f1096SBen Tyner } 123188f1096SBen Tyner } 124188f1096SBen Tyner 125188f1096SBen Tyner return plid; // platform log id or 0 126188f1096SBen Tyner } 127188f1096SBen Tyner 128188f1096SBen Tyner /** @brief Create a PEL from raw PEL data */ 129188f1096SBen Tyner void createPelRaw(const std::vector<uint8_t>& i_buffer) 130188f1096SBen Tyner { 131188f1096SBen Tyner // Create FFDC file from buffer data 132188f1096SBen Tyner util::FFDCFile pelFile{util::FFDCFormat::Text}; 133188f1096SBen Tyner auto fd = pelFile.getFileDescriptor(); 134188f1096SBen Tyner 135188f1096SBen Tyner auto filePath = pelFile.getPath(); // path to ffdc file 136188f1096SBen Tyner 137*d700609cSBen Tyner size_t numBytes = write(fd, i_buffer.data(), i_buffer.size()); 138*d700609cSBen Tyner if (i_buffer.size() != numBytes) 139*d700609cSBen Tyner { 140*d700609cSBen Tyner std::stringstream traceMsg; 141*d700609cSBen Tyner traceMsg << filePath.c_str() << " only " << (int)numBytes << " of " 142*d700609cSBen Tyner << (int)i_buffer.size() << " bytes written"; 143*d700609cSBen Tyner auto strobj = traceMsg.str(); 144*d700609cSBen Tyner trace<level::ERROR>(strobj.c_str()); 145*d700609cSBen Tyner } 146*d700609cSBen Tyner 147*d700609cSBen Tyner lseek(fd, 0, SEEK_SET); 148*d700609cSBen Tyner 149188f1096SBen Tyner // Additional data for log 150188f1096SBen Tyner std::map<std::string, std::string> additional; 151188f1096SBen Tyner additional.emplace("RAWPEL", filePath.string()); 152188f1096SBen Tyner additional.emplace("_PID", std::to_string(getpid())); 153188f1096SBen Tyner 154188f1096SBen Tyner // dbus specifics 155188f1096SBen Tyner constexpr auto interface = "xyz.openbmc_project.Logging.Create"; 156188f1096SBen Tyner constexpr auto function = "Create"; 157188f1096SBen Tyner 158188f1096SBen Tyner sdbusplus::message::message method; 159188f1096SBen Tyner 160188f1096SBen Tyner if (0 == dbusMethod(pathLogging, interface, function, method)) 161188f1096SBen Tyner { 162188f1096SBen Tyner try 163188f1096SBen Tyner { 164188f1096SBen Tyner // append additional dbus call parameters 165188f1096SBen Tyner method.append(eventPelTerminate, levelPelError, additional); 166188f1096SBen Tyner 167188f1096SBen Tyner // using system dbus, no reply 168188f1096SBen Tyner auto bus = sdbusplus::bus::new_system(); 169188f1096SBen Tyner bus.call_noreply(method); 170188f1096SBen Tyner } 171188f1096SBen Tyner catch (const sdbusplus::exception::SdBusError& e) 172188f1096SBen Tyner { 173188f1096SBen Tyner std::stringstream ss; 174188f1096SBen Tyner ss << "createPelRaw exception: " << e.what(); 175188f1096SBen Tyner trace<level::INFO>(ss.str().c_str()); 176188f1096SBen Tyner } 177188f1096SBen Tyner } 178188f1096SBen Tyner } 179188f1096SBen Tyner 180188f1096SBen Tyner /** @brief Get file descriptor of exisitng PEL */ 181188f1096SBen Tyner int getPel(const uint32_t i_pelId) 182188f1096SBen Tyner { 183188f1096SBen Tyner // GetPEL returns file descriptor (int) 184188f1096SBen Tyner int fd = -1; 185188f1096SBen Tyner 186188f1096SBen Tyner // dbus specifics 187188f1096SBen Tyner constexpr auto interface = "org.open_power.Logging.PEL"; 188188f1096SBen Tyner constexpr auto function = "GetPEL"; 189188f1096SBen Tyner 190188f1096SBen Tyner sdbusplus::message::message method; 191188f1096SBen Tyner 192188f1096SBen Tyner if (0 == dbusMethod(pathLogging, interface, function, method)) 193188f1096SBen Tyner { 194188f1096SBen Tyner try 195188f1096SBen Tyner { 196188f1096SBen Tyner // additional dbus call parameters 197188f1096SBen Tyner method.append(i_pelId); 198188f1096SBen Tyner 199188f1096SBen Tyner // using system dbus 200188f1096SBen Tyner auto bus = sdbusplus::bus::new_system(); 201188f1096SBen Tyner auto response = bus.call(method); 202188f1096SBen Tyner 203188f1096SBen Tyner // reply will be a unix file descriptor 204188f1096SBen Tyner sdbusplus::message::unix_fd reply; 205188f1096SBen Tyner 206188f1096SBen Tyner // parse dbus reply 207188f1096SBen Tyner response.read(reply); 208188f1096SBen Tyner 209188f1096SBen Tyner fd = dup(reply); // need to copy (dup) the file descriptor 210188f1096SBen Tyner } 211188f1096SBen Tyner catch (const sdbusplus::exception::SdBusError& e) 212188f1096SBen Tyner { 213188f1096SBen Tyner std::stringstream ss; 214188f1096SBen Tyner ss << "getPel exception: " << e.what(); 215188f1096SBen Tyner trace<level::INFO>(ss.str().c_str()); 216188f1096SBen Tyner } 217188f1096SBen Tyner } 218188f1096SBen Tyner 219188f1096SBen Tyner return fd; // file descriptor or -1 220188f1096SBen Tyner } 221188f1096SBen Tyner 222188f1096SBen Tyner } // namespace attn 223