1 #include <unistd.h>
2 
3 #include <phosphor-logging/log.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 using namespace phosphor::logging;
16 
17 int dbusMethod(const std::string& path, const std::string& interface,
18                const std::string& function, sdbusplus::message_t& method,
19                const std::string& extended)
20 {
21     int rc = RC_DBUS_ERROR; // assume error
22 
23     try
24     {
25         constexpr auto serviceFind = "xyz.openbmc_project.ObjectMapper";
26         constexpr auto pathFind = "/xyz/openbmc_project/object_mapper";
27         constexpr auto interfaceFind = "xyz.openbmc_project.ObjectMapper";
28         constexpr auto functionFind = "GetObject";
29 
30         auto bus = sdbusplus::bus::new_system(); // using system dbus
31 
32         // method to find service from object path and object interface
33         auto newMethod = bus.new_method_call(serviceFind, pathFind,
34                                              interfaceFind, functionFind);
35 
36         // find the service for specified object path and interface
37         newMethod.append(path.c_str());
38         newMethod.append(std::vector<std::string>({interface}));
39         auto reply = bus.call(newMethod);
40 
41         // dbus call results
42         std::map<std::string, std::vector<std::string>> responseFindService;
43         reply.read(responseFindService);
44 
45         // If we successfully found the service associated with the dbus object
46         // path and interface then create a method for the specified interface
47         // and function.
48         if (!responseFindService.empty())
49         {
50             auto service = responseFindService.begin()->first;
51 
52             // Some methods (e.g. get attribute) take an extended parameter
53             if (extended == "")
54             {
55                 // return the method
56                 method =
57                     bus.new_method_call(service.c_str(), path.c_str(),
58                                         interface.c_str(), function.c_str());
59             }
60             else
61             {
62                 // return extended method
63                 method =
64                     bus.new_method_call(service.c_str(), path.c_str(),
65                                         extended.c_str(), function.c_str());
66             }
67 
68             rc = RC_SUCCESS;
69         }
70         else
71         {
72             // This trace will be picked up in event log
73             log<level::INFO>("dbusMethod service not found");
74             std::string traceMsgPath = std::string(path, maxTraceLen);
75             log<level::INFO>(traceMsgPath.c_str());
76             std::string traceMsgIface = std::string(interface, maxTraceLen);
77             log<level::INFO>(traceMsgIface.c_str());
78         }
79     }
80     catch (const sdbusplus::exception_t& e)
81     {
82         log<level::ERR>("Error in dbusMethod", entry("ERROR=%s", e.what()));
83     }
84 
85     return rc;
86 }
87 
88 uint32_t createPel(const std::string& eventType,
89                    std::map<std::string, std::string>& additional,
90                    const std::vector<FFDCTuple>& ffdc)
91 {
92     // Create returns plid
93     int plid = 0;
94 
95     // Need to provide pid when using create or create-with-ffdc methods
96     additional.emplace("_PID", std::to_string(getpid()));
97 
98     // Sdbus call specifics
99     constexpr auto interface = "org.open_power.Logging.PEL";
100     constexpr auto function = "CreatePELWithFFDCFiles";
101 
102     sdbusplus::message_t method;
103 
104     if (0 == dbusMethod(pathLogging, interface, function, method))
105     {
106         try
107         {
108             // append additional dbus call paramaters
109             method.append(eventType, levelPelError, additional, ffdc);
110 
111             // using system dbus
112             auto bus = sdbusplus::bus::new_system();
113             auto response = bus.call(method);
114 
115             // reply will be tuple containing bmc log id, platform log id
116             std::tuple<uint32_t, uint32_t> reply = {0, 0};
117 
118             // parse dbus response into reply
119             response.read(reply);
120             plid = std::get<1>(reply); // platform log id is tuple "second"
121         }
122         catch (const sdbusplus::exception_t& e)
123         {
124             log<level::ERR>("Error in createPel CreatePELWithFFDCFiles",
125                             entry("ERROR=%s", e.what()));
126         }
127     }
128 
129     return plid; // platform log id or 0
130 }
131 
132 } // namespace dump
133 } // namespace watchdog
134