1 #include <unistd.h> 2 3 #include <phosphor-logging/lg2.hpp> 4 #include <watchdog_dbus.hpp> 5 #include <watchdog_logging.hpp> 6 7 #include <string> 8 #include <vector> 9 10 namespace watchdog 11 { 12 namespace dump 13 { 14 15 int dbusMethod(const std::string& path, const std::string& interface, 16 const std::string& function, sdbusplus::message_t& method, 17 const std::string& extended) 18 { 19 int rc = RC_DBUS_ERROR; // assume error 20 21 try 22 { 23 constexpr auto serviceFind = "xyz.openbmc_project.ObjectMapper"; 24 constexpr auto pathFind = "/xyz/openbmc_project/object_mapper"; 25 constexpr auto interfaceFind = "xyz.openbmc_project.ObjectMapper"; 26 constexpr auto functionFind = "GetObject"; 27 28 auto bus = sdbusplus::bus::new_system(); // using system dbus 29 30 // method to find service from object path and object interface 31 auto newMethod = bus.new_method_call(serviceFind, pathFind, 32 interfaceFind, functionFind); 33 34 // find the service for specified object path and interface 35 newMethod.append(path.c_str()); 36 newMethod.append(std::vector<std::string>({interface})); 37 auto reply = bus.call(newMethod); 38 39 // dbus call results 40 std::map<std::string, std::vector<std::string>> responseFindService; 41 reply.read(responseFindService); 42 43 // If we successfully found the service associated with the dbus object 44 // path and interface then create a method for the specified interface 45 // and function. 46 if (!responseFindService.empty()) 47 { 48 auto service = responseFindService.begin()->first; 49 50 // Some methods (e.g. get attribute) take an extended parameter 51 if (extended == "") 52 { 53 // return the method 54 method = 55 bus.new_method_call(service.c_str(), path.c_str(), 56 interface.c_str(), function.c_str()); 57 } 58 else 59 { 60 // return extended method 61 method = 62 bus.new_method_call(service.c_str(), path.c_str(), 63 extended.c_str(), function.c_str()); 64 } 65 66 rc = RC_SUCCESS; 67 } 68 else 69 { 70 // This trace will be picked up in event log 71 lg2::info("dbusMethod service not found"); 72 std::string traceMsgPath = std::string(path, maxTraceLen); 73 lg2::info(traceMsgPath.c_str()); 74 std::string traceMsgIface = std::string(interface, maxTraceLen); 75 lg2::info(traceMsgIface.c_str()); 76 } 77 } 78 catch (const sdbusplus::exception_t& e) 79 { 80 lg2::error("Error in dbusMethod ({ERROR})", "ERROR", e); 81 } 82 83 return rc; 84 } 85 86 uint32_t createPel(const std::string& eventType, 87 std::map<std::string, std::string>& additional, 88 const std::vector<FFDCTuple>& ffdc) 89 { 90 // Create returns plid 91 int plid = 0; 92 93 // Need to provide pid when using create or create-with-ffdc methods 94 additional.emplace("_PID", std::to_string(getpid())); 95 96 // Sdbus call specifics 97 constexpr auto interface = "org.open_power.Logging.PEL"; 98 constexpr auto function = "CreatePELWithFFDCFiles"; 99 100 sdbusplus::message_t method; 101 102 if (0 == dbusMethod(pathLogging, interface, function, method)) 103 { 104 try 105 { 106 // append additional dbus call parameters 107 method.append(eventType, levelPelError, additional, ffdc); 108 109 // using system dbus 110 auto bus = sdbusplus::bus::new_system(); 111 auto response = bus.call(method); 112 113 // reply will be tuple containing bmc log id, platform log id 114 std::tuple<uint32_t, uint32_t> reply = {0, 0}; 115 116 // parse dbus response into reply 117 response.read(reply); 118 plid = std::get<1>(reply); // platform log id is tuple "second" 119 } 120 catch (const sdbusplus::exception_t& e) 121 { 122 lg2::error("Error in createPel CreatePELWithFFDCFiles ({ERROR})", 123 "ERROR", e); 124 } 125 } 126 127 return plid; // platform log id or 0 128 } 129 130 bool isHostStateRunning() 131 { 132 constexpr auto path = "/xyz/openbmc_project/state/host0"; 133 constexpr auto interface = "xyz.openbmc_project.State.Host"; 134 constexpr auto extended = "org.freedesktop.DBus.Properties"; 135 constexpr auto function = "Get"; 136 137 sdbusplus::message_t method; 138 139 if (0 == dbusMethod(path, interface, function, method, extended)) 140 { 141 try 142 { 143 method.append(interface, "CurrentHostState"); 144 auto bus = sdbusplus::bus::new_system(); 145 auto response = bus.call(method); 146 std::variant<std::string> reply; 147 148 response.read(reply); 149 std::string currentHostState(std::get<std::string>(reply)); 150 151 if (currentHostState == 152 "xyz.openbmc_project.State.Host.HostState.Running") 153 { 154 return true; 155 } 156 } 157 catch (const sdbusplus::exception_t& e) 158 { 159 lg2::error("Failed to read CurrentHostState property ({ERROR})", 160 "ERROR", e); 161 } 162 } 163 164 return false; 165 } 166 167 } // namespace dump 168 } // namespace watchdog 169