1 #include <phosphor-logging/elog-errors.hpp>
2 #include <xyz/openbmc_project/Common/error.hpp>
3 
4 const char* propIntf = "org.freedesktop.DBus.Properties";
5 const char* mapperBusName = "xyz.openbmc_project.ObjectMapper";
6 const char* mapperPath = "/xyz/openbmc_project/object_mapper";
7 const char* mapperIntf = "xyz.openbmc_project.ObjectMapper";
8 
9 const char* methodGetObject = "GetObject";
10 const char* methodGet = "Get";
11 
12 using namespace sdbusplus::xyz::openbmc_project::Common::Error;
13 
14 using Value = std::variant<int64_t, double, std::string, bool>;
15 
16 std::string getService(sdbusplus::bus_t& bus, const std::string& path,
17                        const char* intf)
18 {
19     /* Get mapper object for sensor path */
20     auto mapper = bus.new_method_call(mapperBusName, mapperPath, mapperIntf,
21                                       methodGetObject);
22 
23     mapper.append(path.c_str());
24     mapper.append(std::vector<std::string>({intf}));
25 
26     std::unordered_map<std::string, std::vector<std::string>> resp;
27 
28     try
29     {
30         auto msg = bus.call(mapper);
31         msg.read(resp);
32     }
33     catch (const sdbusplus::exception_t& ex)
34     {
35         if (ex.name() == std::string(sdbusplus::xyz::openbmc_project::Common::
36                                          Error::ResourceNotFound::errName))
37         {
38             // The service isn't on D-Bus yet.
39             return std::string{};
40         }
41 
42         throw;
43     }
44 
45     if (resp.begin() == resp.end())
46     {
47         // Shouldn't happen, if the mapper can't find it it is handled above.
48         throw std::runtime_error("Unable to find Object: " + path);
49     }
50 
51     return resp.begin()->first;
52 }
53 
54 template <typename T>
55 
56 T getDbusProperty(sdbusplus::bus_t& bus, const std::string& service,
57                   const std::string& path, const std::string& intf,
58                   const std::string& property)
59 {
60     Value value;
61 
62     auto method =
63         bus.new_method_call(service.c_str(), path.c_str(), propIntf, methodGet);
64 
65     method.append(intf, property);
66 
67     try
68     {
69         auto msg = bus.call(method);
70         msg.read(value);
71     }
72     catch (const sdbusplus::exception_t& ex)
73     {
74         return std::numeric_limits<T>::quiet_NaN();
75     }
76 
77     return std::get<T>(value);
78 }
79