blob: 778dbd804507d0c087e386163fcf6692fdcedd3b [file] [log] [blame]
Patrick Venture0b02be92018-08-31 11:55:55 -07001#include "settings.hpp"
2
Vernon Mauery6a98fe72019-03-11 15:57:48 -07003#include <ipmid/utils.hpp>
Deepak Kodihalli18aa0442017-07-21 07:07:09 -05004#include <phosphor-logging/elog-errors.hpp>
5#include <phosphor-logging/log.hpp>
William A. Kennington III4c008022018-10-12 17:18:14 -07006#include <sdbusplus/message/types.hpp>
Patrick Venture0b02be92018-08-31 11:55:55 -07007#include <xyz/openbmc_project/Common/error.hpp>
Deepak Kodihalli18aa0442017-07-21 07:07:09 -05008
9namespace settings
10{
11
12using namespace phosphor::logging;
13using namespace sdbusplus::xyz::openbmc_project::Common::Error;
14
15constexpr auto mapperService = "xyz.openbmc_project.ObjectMapper";
16constexpr auto mapperPath = "/xyz/openbmc_project/object_mapper";
17constexpr auto mapperIntf = "xyz.openbmc_project.ObjectMapper";
18
Patrick Williams5d82f472022-07-22 19:26:53 -050019Objects::Objects(sdbusplus::bus_t& bus, const std::vector<Interface>& filter) :
Deepak Kodihalli18aa0442017-07-21 07:07:09 -050020 bus(bus)
21{
22 auto depth = 0;
23
Patrick Venture0b02be92018-08-31 11:55:55 -070024 auto mapperCall = bus.new_method_call(mapperService, mapperPath, mapperIntf,
Deepak Kodihalli18aa0442017-07-21 07:07:09 -050025 "GetSubTree");
26 mapperCall.append(root);
27 mapperCall.append(depth);
28 mapperCall.append(filter);
29 auto response = bus.call(mapperCall);
30 if (response.is_method_error())
31 {
32 log<level::ERR>("Error in mapper GetSubTree");
33 elog<InternalFailure>();
34 }
35
36 using Interfaces = std::vector<Interface>;
37 using MapperResponse = std::map<Path, std::map<Service, Interfaces>>;
38 MapperResponse result;
39 response.read(result);
40 if (result.empty())
41 {
42 log<level::ERR>("Invalid response from mapper");
43 elog<InternalFailure>();
44 }
45
46 for (auto& iter : result)
47 {
48 const auto& path = iter.first;
Deepak Kodihallie6027092017-08-27 08:13:37 -050049 for (auto& interface : iter.second.begin()->second)
50 {
51 auto found = map.find(interface);
52 if (map.end() != found)
53 {
54 auto& paths = found->second;
55 paths.push_back(path);
56 }
57 else
58 {
59 map.emplace(std::move(interface), std::vector<Path>({path}));
60 }
61 }
Deepak Kodihalli18aa0442017-07-21 07:07:09 -050062 }
63}
64
65Service Objects::service(const Path& path, const Interface& interface) const
66{
67 using Interfaces = std::vector<Interface>;
Patrick Venture0b02be92018-08-31 11:55:55 -070068 auto mapperCall =
69 bus.new_method_call(mapperService, mapperPath, mapperIntf, "GetObject");
Deepak Kodihalli18aa0442017-07-21 07:07:09 -050070 mapperCall.append(path);
71 mapperCall.append(Interfaces({interface}));
72
73 auto response = bus.call(mapperCall);
74 if (response.is_method_error())
75 {
76 log<level::ERR>("Error in mapper GetObject");
77 elog<InternalFailure>();
78 }
79
80 std::map<Service, Interfaces> result;
81 response.read(result);
82 if (result.empty())
83 {
84 log<level::ERR>("Invalid response from mapper");
85 elog<InternalFailure>();
86 }
87
88 return result.begin()->first;
89}
90
Deepak Kodihalli13791bd2017-08-28 06:50:51 -050091namespace boot
92{
93
94std::tuple<Path, OneTimeEnabled> setting(const Objects& objects,
95 const Interface& iface)
96{
97 constexpr auto bootObjCount = 2;
98 constexpr auto oneTime = "one_time";
99 constexpr auto enabledIntf = "xyz.openbmc_project.Object.Enable";
100
101 const std::vector<Path>& paths = objects.map.at(iface);
102 auto count = paths.size();
103 if (count != bootObjCount)
104 {
105 log<level::ERR>("Exactly two objects expected",
106 entry("INTERFACE=%s", iface.c_str()),
107 entry("COUNT=%d", count));
108 elog<InternalFailure>();
109 }
110 size_t index = 0;
111 if (std::string::npos == paths[0].rfind(oneTime))
112 {
113 index = 1;
114 }
115 const Path& oneTimeSetting = paths[index];
116 const Path& regularSetting = paths[!index];
117
Patrick Venture0b02be92018-08-31 11:55:55 -0700118 auto method = objects.bus.new_method_call(
119 objects.service(oneTimeSetting, iface).c_str(), oneTimeSetting.c_str(),
120 ipmi::PROP_INTF, "Get");
Deepak Kodihalli13791bd2017-08-28 06:50:51 -0500121 method.append(enabledIntf, "Enabled");
122 auto reply = objects.bus.call(method);
123 if (reply.is_method_error())
124 {
125 log<level::ERR>("Error in getting Enabled property",
126 entry("OBJECT=%s", oneTimeSetting.c_str()),
127 entry("INTERFACE=%s", iface.c_str()));
128 elog<InternalFailure>();
129 }
130
Vernon Mauery16b86932019-05-01 08:36:11 -0700131 std::variant<bool> enabled;
Deepak Kodihalli13791bd2017-08-28 06:50:51 -0500132 reply.read(enabled);
Vernon Maueryf442e112019-04-09 11:44:36 -0700133 auto oneTimeEnabled = std::get<bool>(enabled);
Deepak Kodihalli13791bd2017-08-28 06:50:51 -0500134 const Path& setting = oneTimeEnabled ? oneTimeSetting : regularSetting;
135 return std::make_tuple(setting, oneTimeEnabled);
136}
137
138} // namespace boot
139
Deepak Kodihalli18aa0442017-07-21 07:07:09 -0500140} // namespace settings