blob: e8b8997678c0bd2ff5c99b2d3c58d1a2b64e6871 [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;
William A. Kennington III4c008022018-10-12 17:18:14 -070014namespace variant_ns = sdbusplus::message::variant_ns;
Deepak Kodihalli18aa0442017-07-21 07:07:09 -050015
16constexpr auto mapperService = "xyz.openbmc_project.ObjectMapper";
17constexpr auto mapperPath = "/xyz/openbmc_project/object_mapper";
18constexpr auto mapperIntf = "xyz.openbmc_project.ObjectMapper";
19
20Objects::Objects(sdbusplus::bus::bus& bus,
Patrick Venture0b02be92018-08-31 11:55:55 -070021 const std::vector<Interface>& filter) :
Deepak Kodihalli18aa0442017-07-21 07:07:09 -050022 bus(bus)
23{
24 auto depth = 0;
25
Patrick Venture0b02be92018-08-31 11:55:55 -070026 auto mapperCall = bus.new_method_call(mapperService, mapperPath, mapperIntf,
Deepak Kodihalli18aa0442017-07-21 07:07:09 -050027 "GetSubTree");
28 mapperCall.append(root);
29 mapperCall.append(depth);
30 mapperCall.append(filter);
31 auto response = bus.call(mapperCall);
32 if (response.is_method_error())
33 {
34 log<level::ERR>("Error in mapper GetSubTree");
35 elog<InternalFailure>();
36 }
37
38 using Interfaces = std::vector<Interface>;
39 using MapperResponse = std::map<Path, std::map<Service, Interfaces>>;
40 MapperResponse result;
41 response.read(result);
42 if (result.empty())
43 {
44 log<level::ERR>("Invalid response from mapper");
45 elog<InternalFailure>();
46 }
47
48 for (auto& iter : result)
49 {
50 const auto& path = iter.first;
Deepak Kodihallie6027092017-08-27 08:13:37 -050051 for (auto& interface : iter.second.begin()->second)
52 {
53 auto found = map.find(interface);
54 if (map.end() != found)
55 {
56 auto& paths = found->second;
57 paths.push_back(path);
58 }
59 else
60 {
61 map.emplace(std::move(interface), std::vector<Path>({path}));
62 }
63 }
Deepak Kodihalli18aa0442017-07-21 07:07:09 -050064 }
65}
66
67Service Objects::service(const Path& path, const Interface& interface) const
68{
69 using Interfaces = std::vector<Interface>;
Patrick Venture0b02be92018-08-31 11:55:55 -070070 auto mapperCall =
71 bus.new_method_call(mapperService, mapperPath, mapperIntf, "GetObject");
Deepak Kodihalli18aa0442017-07-21 07:07:09 -050072 mapperCall.append(path);
73 mapperCall.append(Interfaces({interface}));
74
75 auto response = bus.call(mapperCall);
76 if (response.is_method_error())
77 {
78 log<level::ERR>("Error in mapper GetObject");
79 elog<InternalFailure>();
80 }
81
82 std::map<Service, Interfaces> result;
83 response.read(result);
84 if (result.empty())
85 {
86 log<level::ERR>("Invalid response from mapper");
87 elog<InternalFailure>();
88 }
89
90 return result.begin()->first;
91}
92
Deepak Kodihalli13791bd2017-08-28 06:50:51 -050093namespace boot
94{
95
96std::tuple<Path, OneTimeEnabled> setting(const Objects& objects,
97 const Interface& iface)
98{
99 constexpr auto bootObjCount = 2;
100 constexpr auto oneTime = "one_time";
101 constexpr auto enabledIntf = "xyz.openbmc_project.Object.Enable";
102
103 const std::vector<Path>& paths = objects.map.at(iface);
104 auto count = paths.size();
105 if (count != bootObjCount)
106 {
107 log<level::ERR>("Exactly two objects expected",
108 entry("INTERFACE=%s", iface.c_str()),
109 entry("COUNT=%d", count));
110 elog<InternalFailure>();
111 }
112 size_t index = 0;
113 if (std::string::npos == paths[0].rfind(oneTime))
114 {
115 index = 1;
116 }
117 const Path& oneTimeSetting = paths[index];
118 const Path& regularSetting = paths[!index];
119
Patrick Venture0b02be92018-08-31 11:55:55 -0700120 auto method = objects.bus.new_method_call(
121 objects.service(oneTimeSetting, iface).c_str(), oneTimeSetting.c_str(),
122 ipmi::PROP_INTF, "Get");
Deepak Kodihalli13791bd2017-08-28 06:50:51 -0500123 method.append(enabledIntf, "Enabled");
124 auto reply = objects.bus.call(method);
125 if (reply.is_method_error())
126 {
127 log<level::ERR>("Error in getting Enabled property",
128 entry("OBJECT=%s", oneTimeSetting.c_str()),
129 entry("INTERFACE=%s", iface.c_str()));
130 elog<InternalFailure>();
131 }
132
133 sdbusplus::message::variant<bool> enabled;
134 reply.read(enabled);
William A. Kennington III4c008022018-10-12 17:18:14 -0700135 auto oneTimeEnabled = variant_ns::get<bool>(enabled);
Deepak Kodihalli13791bd2017-08-28 06:50:51 -0500136 const Path& setting = oneTimeEnabled ? oneTimeSetting : regularSetting;
137 return std::make_tuple(setting, oneTimeEnabled);
138}
139
140} // namespace boot
141
Deepak Kodihalli18aa0442017-07-21 07:07:09 -0500142} // namespace settings