1 #include <phosphor-logging/elog-errors.hpp>
2 #include <phosphor-logging/log.hpp>
3 #include <sdbusplus/exception.hpp>
4 #include "xyz/openbmc_project/Common/error.hpp"
5 #include "settings.hpp"
6 
7 namespace settings
8 {
9 
10 using namespace phosphor::logging;
11 using namespace sdbusplus::xyz::openbmc_project::Common::Error;
12 using sdbusplus::exception::SdBusError;
13 
14 constexpr auto mapperService = "xyz.openbmc_project.ObjectMapper";
15 constexpr auto mapperPath = "/xyz/openbmc_project/object_mapper";
16 constexpr auto mapperIntf = "xyz.openbmc_project.ObjectMapper";
17 
18 Objects::Objects(sdbusplus::bus::bus& bus) : bus(bus)
19 {
20     std::vector<std::string> settingsIntfs = {autoRebootIntf, powerRestoreIntf};
21     auto depth = 0;
22 
23     auto mapperCall = bus.new_method_call(mapperService, mapperPath, mapperIntf,
24                                           "GetSubTree");
25     mapperCall.append(root);
26     mapperCall.append(depth);
27     mapperCall.append(settingsIntfs);
28 
29     using Interfaces = std::vector<Interface>;
30     using MapperResponse = std::map<Path, std::map<Service, Interfaces>>;
31     MapperResponse result;
32 
33     try
34     {
35         auto response = bus.call(mapperCall);
36 
37         response.read(result);
38         if (result.empty())
39         {
40             log<level::ERR>("Invalid response from mapper");
41             elog<InternalFailure>();
42         }
43     }
44     catch (const SdBusError& e)
45     {
46         log<level::ERR>("Error in mapper GetSubTree",
47                         entry("ERROR=%s", e.what()));
48         elog<InternalFailure>();
49     }
50 
51     for (const auto& iter : result)
52     {
53         const Path& path = iter.first;
54 
55         for (const auto& serviceIter : iter.second)
56         {
57             for (const auto& interface : serviceIter.second)
58             {
59                 if (autoRebootIntf == interface)
60                 {
61                     autoReboot = path;
62                 }
63                 else if (powerRestoreIntf == interface)
64                 {
65                     powerRestorePolicy = path;
66                 }
67             }
68         }
69     }
70 }
71 
72 Service Objects::service(const Path& path, const Interface& interface) const
73 {
74     using Interfaces = std::vector<Interface>;
75     auto mapperCall =
76         bus.new_method_call(mapperService, mapperPath, mapperIntf, "GetObject");
77     mapperCall.append(path);
78     mapperCall.append(Interfaces({interface}));
79 
80     std::map<Service, Interfaces> result;
81 
82     try
83     {
84         auto response = bus.call(mapperCall);
85         response.read(result);
86     }
87     catch (const SdBusError& e)
88     {
89         log<level::ERR>("Error in mapper GetObject",
90                         entry("ERROR=%s", e.what()));
91         elog<InternalFailure>();
92     }
93 
94     if (result.empty())
95     {
96         log<level::ERR>("Invalid response from mapper");
97         elog<InternalFailure>();
98     }
99 
100     return result.begin()->first;
101 }
102 
103 } // namespace settings
104