blob: 2ecad0c419e57f82c4e8945d04ac7b2b1cd6278f [file] [log] [blame]
Andrew Geissler32016d12017-06-20 15:46:52 -05001#include <powercap.hpp>
2#include <phosphor-logging/log.hpp>
3
4namespace open_power
5{
6namespace occ
7{
8namespace powercap
9{
10
Andrew Geissler52cf26a2017-07-06 12:56:32 -050011constexpr auto PCAP_PATH = "/xyz/openbmc_project/control/host0/power_cap";
12constexpr auto PCAP_INTERFACE = "xyz.openbmc_project.Control.Power.Cap";
13
14constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
15constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
16constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
17
18constexpr auto POWER_CAP_PROP = "PowerCap";
19constexpr auto POWER_CAP_ENABLE_PROP = "PowerCapEnable";
20
Andrew Geissler32016d12017-06-20 15:46:52 -050021using namespace phosphor::logging;
22
Andrew Geissler52cf26a2017-07-06 12:56:32 -050023std::string PowerCap::getService(std::string path,
24 std::string interface)
25{
26 auto mapper = bus.new_method_call(MAPPER_BUSNAME,
27 MAPPER_PATH,
28 MAPPER_INTERFACE,
29 "GetObject");
30
31 mapper.append(path, std::vector<std::string>({interface}));
32 auto mapperResponseMsg = bus.call(mapper);
33
34 if (mapperResponseMsg.is_method_error())
35 {
36 log<level::ERR>("Error in mapper call",
37 entry("PATH=%s", path.c_str()),
38 entry("INTERFACE=%s", interface.c_str()));
39 // TODO openbmc/openbmc#851 - Once available, throw returned error
40 throw std::runtime_error("Error in mapper call");
41 }
42
43 std::map<std::string, std::vector<std::string>> mapperResponse;
44 mapperResponseMsg.read(mapperResponse);
45 if (mapperResponse.empty())
46 {
47 log<level::ERR>("Error reading mapper response",
48 entry("PATH=%s", path.c_str()),
49 entry("INTERFACE=%s", interface.c_str()));
50 // TODO openbmc/openbmc#1712 - Handle empty mapper resp. consistently
51 throw std::runtime_error("Error reading mapper response");
52 }
53
54 return mapperResponse.begin()->first;
55}
56
57uint32_t PowerCap::getPcap()
58{
59 auto settingService = getService(PCAP_PATH,PCAP_INTERFACE);
60
61 auto method = this->bus.new_method_call(settingService.c_str(),
62 PCAP_PATH,
63 "org.freedesktop.DBus.Properties",
64 "Get");
65
66 method.append(PCAP_INTERFACE, POWER_CAP_PROP);
67 auto reply = this->bus.call(method);
68
69 if (reply.is_method_error())
70 {
71 log<level::ERR>("Error in getPcap prop");
72 return 0;
73 }
74 sdbusplus::message::variant<uint32_t> pcap;
75 reply.read(pcap);
76
77 return pcap.get<uint32_t>();
78}
79
80bool PowerCap::getPcapEnabled()
81{
82 auto settingService = getService(PCAP_PATH,PCAP_INTERFACE);
83
84 auto method = this->bus.new_method_call(settingService.c_str(),
85 PCAP_PATH,
86 "org.freedesktop.DBus.Properties",
87 "Get");
88
89 method.append(PCAP_INTERFACE, POWER_CAP_ENABLE_PROP);
90 auto reply = this->bus.call(method);
91
92 if (reply.is_method_error())
93 {
94 log<level::ERR>("Error in getPcapEnabled prop");
95 return 0;
96 }
97 sdbusplus::message::variant<bool> pcapEnabled;
98 reply.read(pcapEnabled);
99
100 return pcapEnabled.get<bool>();
101}
Andrew Geissler32016d12017-06-20 15:46:52 -0500102
103void PowerCap::pcapChanged(sdbusplus::message::message& msg)
104{
Andrew Geissler32016d12017-06-20 15:46:52 -0500105 if (!occStatus.occActive())
106 {
107 // Nothing to do
108 return;
109 }
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500110
111 uint32_t pcap = 0;
112 bool pcapEnabled = false;
113
114 std::string msgSensor;
115 std::map<std::string, sdbusplus::message::variant<uint32_t, bool>> msgData;
116 msg.read(msgSensor, msgData);
117
118 // Retrieve which property changed via the msg and read the other one
119 auto valPropMap = msgData.find(POWER_CAP_PROP);
120 if (valPropMap != msgData.end())
121 {
122 pcap = sdbusplus::message::variant_ns::get<uint32_t>(
123 valPropMap->second);
124 pcapEnabled = getPcapEnabled();
125 }
126 else
127 {
128 valPropMap = msgData.find(POWER_CAP_ENABLE_PROP);
129 if (valPropMap != msgData.end())
130 {
131 pcapEnabled = sdbusplus::message::variant_ns::get<bool>(
132 valPropMap->second);
133 pcap = getPcap();
134 }
135 else
136 {
137 log<level::INFO>("Unknown power cap property changed");
138 return;
139 }
140 }
141
142 log<level::INFO>("Power Cap Property Change",
143 entry("PCAP=%u",pcap),
144 entry("PCAP_ENABLED=%u",pcapEnabled));
145
146 // Determine desired action to write to occ
147 // TODO
148
149 // Write action to occ
150 // TODO
151
152 return;
Andrew Geissler32016d12017-06-20 15:46:52 -0500153}
154
155} // namespace open_power
156
157} // namespace occ
158
159}// namespace powercap