blob: bf7c11ddfdbfbc825ded62ebb6a5e928fe07d14c [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;
Willy Tu523e2d12023-09-05 11:36:48 -070013using namespace sdbusplus::error::xyz::openbmc_project::common;
Deepak Kodihalli18aa0442017-07-21 07:07:09 -050014
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);
Deepak Kodihalli18aa0442017-07-21 07:07:09 -050029
30 using Interfaces = std::vector<Interface>;
31 using MapperResponse = std::map<Path, std::map<Service, Interfaces>>;
32 MapperResponse result;
George Liu3e3cc352023-07-26 15:59:31 +080033 try
Deepak Kodihalli18aa0442017-07-21 07:07:09 -050034 {
George Liu3e3cc352023-07-26 15:59:31 +080035 auto response = bus.call(mapperCall);
36 response.read(result);
37 }
38 catch (const std::exception& e)
39 {
40 log<level::ERR>("Error in mapper GetSubTree",
41 entry("ERROR=%s", e.what()));
Deepak Kodihalli18aa0442017-07-21 07:07:09 -050042 elog<InternalFailure>();
43 }
44
45 for (auto& iter : result)
46 {
47 const auto& path = iter.first;
Deepak Kodihallie6027092017-08-27 08:13:37 -050048 for (auto& interface : iter.second.begin()->second)
49 {
50 auto found = map.find(interface);
51 if (map.end() != found)
52 {
53 auto& paths = found->second;
54 paths.push_back(path);
55 }
56 else
57 {
58 map.emplace(std::move(interface), std::vector<Path>({path}));
59 }
60 }
Deepak Kodihalli18aa0442017-07-21 07:07:09 -050061 }
62}
63
64Service Objects::service(const Path& path, const Interface& interface) const
65{
66 using Interfaces = std::vector<Interface>;
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -050067 auto mapperCall = bus.new_method_call(mapperService, mapperPath, mapperIntf,
68 "GetObject");
Deepak Kodihalli18aa0442017-07-21 07:07:09 -050069 mapperCall.append(path);
70 mapperCall.append(Interfaces({interface}));
71
Deepak Kodihalli18aa0442017-07-21 07:07:09 -050072 std::map<Service, Interfaces> result;
George Liu3e3cc352023-07-26 15:59:31 +080073 try
Deepak Kodihalli18aa0442017-07-21 07:07:09 -050074 {
George Liu3e3cc352023-07-26 15:59:31 +080075 auto response = bus.call(mapperCall);
76 response.read(result);
77 return result.begin()->first;
78 }
79 catch (const std::exception& e)
80 {
81 log<level::ERR>("Invalid response from mapper",
82 entry("ERROR=%s", e.what()));
Deepak Kodihalli18aa0442017-07-21 07:07:09 -050083 elog<InternalFailure>();
84 }
Deepak Kodihalli18aa0442017-07-21 07:07:09 -050085}
86
Deepak Kodihalli13791bd2017-08-28 06:50:51 -050087namespace boot
88{
89
90std::tuple<Path, OneTimeEnabled> setting(const Objects& objects,
91 const Interface& iface)
92{
93 constexpr auto bootObjCount = 2;
94 constexpr auto oneTime = "one_time";
95 constexpr auto enabledIntf = "xyz.openbmc_project.Object.Enable";
96
97 const std::vector<Path>& paths = objects.map.at(iface);
98 auto count = paths.size();
99 if (count != bootObjCount)
100 {
101 log<level::ERR>("Exactly two objects expected",
102 entry("INTERFACE=%s", iface.c_str()),
103 entry("COUNT=%d", count));
104 elog<InternalFailure>();
105 }
106 size_t index = 0;
107 if (std::string::npos == paths[0].rfind(oneTime))
108 {
109 index = 1;
110 }
111 const Path& oneTimeSetting = paths[index];
112 const Path& regularSetting = paths[!index];
113
Patrick Venture0b02be92018-08-31 11:55:55 -0700114 auto method = objects.bus.new_method_call(
115 objects.service(oneTimeSetting, iface).c_str(), oneTimeSetting.c_str(),
116 ipmi::PROP_INTF, "Get");
Deepak Kodihalli13791bd2017-08-28 06:50:51 -0500117 method.append(enabledIntf, "Enabled");
George Liu3e3cc352023-07-26 15:59:31 +0800118
119 std::variant<bool> enabled;
120 try
121 {
122 auto reply = objects.bus.call(method);
123 reply.read(enabled);
124 }
125 catch (const std::exception& e)
Deepak Kodihalli13791bd2017-08-28 06:50:51 -0500126 {
127 log<level::ERR>("Error in getting Enabled property",
128 entry("OBJECT=%s", oneTimeSetting.c_str()),
George Liu3e3cc352023-07-26 15:59:31 +0800129 entry("INTERFACE=%s", iface.c_str()),
130 entry("ERROR=%s", e.what()));
Deepak Kodihalli13791bd2017-08-28 06:50:51 -0500131 elog<InternalFailure>();
132 }
133
Vernon Maueryf442e112019-04-09 11:44:36 -0700134 auto oneTimeEnabled = std::get<bool>(enabled);
Deepak Kodihalli13791bd2017-08-28 06:50:51 -0500135 const Path& setting = oneTimeEnabled ? oneTimeSetting : regularSetting;
136 return std::make_tuple(setting, oneTimeEnabled);
137}
138
139} // namespace boot
140
Deepak Kodihalli18aa0442017-07-21 07:07:09 -0500141} // namespace settings