blob: 99ce739186450370052d7b5dc88e975969f0f49f [file] [log] [blame]
George Liud6a1bae2022-06-20 13:47:31 +08001#include "button_handler.hpp"
Matt Spinler69f93512018-11-26 14:55:58 -06002
Delphine CC Chiu15c60e22024-04-12 13:01:32 -05003#include "config.hpp"
Rush Chen31ce3752024-11-08 14:57:27 +08004#include "gpio.hpp"
Matt Spinler1a309f72023-04-04 13:12:19 -05005#include "power_button_profile_factory.hpp"
6
George Liu9fb15972022-06-20 14:54:38 +08007#include <phosphor-logging/lg2.hpp>
Rush Chen31ce3752024-11-08 14:57:27 +08008#include <xyz/openbmc_project/Chassis/Buttons/Power/server.hpp>
Matt Spinler963c65f2018-11-26 14:46:41 -06009#include <xyz/openbmc_project/State/Chassis/server.hpp>
10#include <xyz/openbmc_project/State/Host/server.hpp>
Rush Chen31ce3752024-11-08 14:57:27 +080011
12#include <fstream>
13#include <iostream>
14#include <string>
15
Matt Spinlerfb35a322018-11-26 14:30:30 -060016namespace phosphor
17{
18namespace button
19{
Matt Spinler963c65f2018-11-26 14:46:41 -060020
21namespace sdbusRule = sdbusplus::bus::match::rules;
22using namespace sdbusplus::xyz::openbmc_project::State::server;
Rush Chen31ce3752024-11-08 14:57:27 +080023using namespace sdbusplus::xyz::openbmc_project::Chassis::Buttons::server;
24
25const std::map<std::string, Chassis::Transition> chassisPwrCtls = {
26 {"chassis-on", Chassis::Transition::On},
27 {"chassis-off", Chassis::Transition::Off},
28 {"chassis-cycle", Chassis::Transition::PowerCycle}};
Matt Spinler963c65f2018-11-26 14:46:41 -060029
Matt Spinler963c65f2018-11-26 14:46:41 -060030constexpr auto chassisIface = "xyz.openbmc_project.State.Chassis";
31constexpr auto hostIface = "xyz.openbmc_project.State.Host";
32constexpr auto powerButtonIface = "xyz.openbmc_project.Chassis.Buttons.Power";
Matt Spinler69f93512018-11-26 14:55:58 -060033constexpr auto idButtonIface = "xyz.openbmc_project.Chassis.Buttons.ID";
Matt Spinler06a5bdd2018-11-26 14:50:48 -060034constexpr auto resetButtonIface = "xyz.openbmc_project.Chassis.Buttons.Reset";
Matt Spinler69f93512018-11-26 14:55:58 -060035constexpr auto ledGroupIface = "xyz.openbmc_project.Led.Group";
Naveen Moses3bd1cfc2022-02-14 18:04:20 +053036constexpr auto ledGroupBasePath = "/xyz/openbmc_project/led/groups/";
37constexpr auto hostSelectorIface =
38 "xyz.openbmc_project.Chassis.Buttons.HostSelector";
39constexpr auto debugHostSelectorIface =
Naveen Mosesa6d4e652022-04-13 19:27:25 +053040 "xyz.openbmc_project.Chassis.Buttons.Button";
Naveen Moses3bd1cfc2022-02-14 18:04:20 +053041
42constexpr auto propertyIface = "org.freedesktop.DBus.Properties";
43constexpr auto mapperIface = "xyz.openbmc_project.ObjectMapper";
Matt Spinler963c65f2018-11-26 14:46:41 -060044
45constexpr auto mapperObjPath = "/xyz/openbmc_project/object_mapper";
46constexpr auto mapperService = "xyz.openbmc_project.ObjectMapper";
Naveen Moses3bd1cfc2022-02-14 18:04:20 +053047constexpr auto BMC_POSITION = 0;
Matt Spinler963c65f2018-11-26 14:46:41 -060048
Rush Chen31ce3752024-11-08 14:57:27 +080049std::vector<std::map<uint16_t, Chassis::Transition>> multiPwrBtnActConf;
50
Patrick Williams9a529a62022-07-22 19:26:54 -050051Handler::Handler(sdbusplus::bus_t& bus) : bus(bus)
Matt Spinlerfb35a322018-11-26 14:30:30 -060052{
Rush Chen31ce3752024-11-08 14:57:27 +080053 /* So far, there are two modes for multi-host power control
54 - host select button mode, e.g.: Yosemite V2
55 only one power button with host select switch,
56 which's interface for handling target host,
57 in the case, hostSelectButtonMode = true
58 - multi power button mode, e.g.: Greatlakes
59 each slot/sled has its own power button,
60 in the case, hostSelectButtonMode = false */
61 hostSelectButtonMode =
62 !getService(HS_DBUS_OBJECT_NAME, hostSelectorIface).empty();
63 size_t powerButtonCount = 1;
64 if (!hostSelectButtonMode)
65 {
66 powerButtonCount = phosphor::button::numberOfChassis();
67 }
68
69 std::ifstream gpios{gpioDefFile};
70 auto configDefJson = nlohmann::json::parse(gpios, nullptr, true);
71 nlohmann::json gpioDefs = configDefJson["gpio_definitions"];
72
73 for (const auto& gpioConfig : gpioDefs)
74 {
75 if (gpioConfig.contains("multi-action"))
76 {
77 std::map<uint16_t, Chassis::Transition> mapEntry;
78 const auto& multiActCfg = gpioConfig["multi-action"];
79 for (const auto& ActCfg : multiActCfg)
80 {
81 auto chassisPwrCtl = chassisPwrCtls.find(ActCfg["action"]);
82 if (chassisPwrCtl != chassisPwrCtls.end())
83 {
84 auto duration = ActCfg["duration"].get<uint16_t>();
85 mapEntry[duration] = chassisPwrCtl->second;
86 }
87 else
88 {
89 lg2::error("unknown power button action");
90 }
91 }
92 multiPwrBtnActConf.emplace_back(mapEntry);
93 }
94 else
95 {
96 isButtonMultiActionSupport = false;
97 break;
98 }
99 }
100
Matt Spinler963c65f2018-11-26 14:46:41 -0600101 try
102 {
103 if (!getService(POWER_DBUS_OBJECT_NAME, powerButtonIface).empty())
104 {
George Liu9fb15972022-06-20 14:54:38 +0800105 lg2::info("Starting power button handler");
Matt Spinler1a309f72023-04-04 13:12:19 -0500106
107 // Check for a custom handler
108 powerButtonProfile =
109 PowerButtonProfileFactory::instance().createProfile(bus);
110
111 if (!powerButtonProfile)
112 {
113 powerButtonReleased = std::make_unique<sdbusplus::bus::match_t>(
114 bus,
115 sdbusRule::type::signal() + sdbusRule::member("Released") +
116 sdbusRule::path(POWER_DBUS_OBJECT_NAME) +
117 sdbusRule::interface(powerButtonIface),
118 std::bind(std::mem_fn(&Handler::powerReleased), this,
119 std::placeholders::_1));
120 }
Matt Spinler963c65f2018-11-26 14:46:41 -0600121 }
Rush Chen31ce3752024-11-08 14:57:27 +0800122
123 if (!hostSelectButtonMode && isButtonMultiActionSupport)
124 {
125 lg2::info("Starting multi power button handler");
126 // The index, 'countIter', starts at 1 and increments,
127 // representing slot_1 through slot_N.
128 for (size_t countIter = 1; countIter <= powerButtonCount;
129 countIter++)
130 {
131 std::unique_ptr<sdbusplus::bus::match_t>
132 multiPowerReleaseMatch =
133 std::make_unique<sdbusplus::bus::match_t>(
134 bus,
135 sdbusRule::type::signal() +
136 sdbusRule::member("Released") +
137 sdbusRule::path(POWER_DBUS_OBJECT_NAME +
138 std::to_string(countIter)) +
139 sdbusRule::interface(powerButtonIface),
140 std::bind(std::mem_fn(&Handler::powerReleased),
141 this, std::placeholders::_1));
142 multiPowerButtonReleased.emplace_back(
143 std::move(multiPowerReleaseMatch));
144 }
145 }
Matt Spinler963c65f2018-11-26 14:46:41 -0600146 }
Patrick Williams9a529a62022-07-22 19:26:54 -0500147 catch (const sdbusplus::exception_t& e)
Matt Spinler963c65f2018-11-26 14:46:41 -0600148 {
Rush Chen31ce3752024-11-08 14:57:27 +0800149 lg2::error("Error creating power button handler: {ERROR}", "ERROR", e);
Matt Spinler963c65f2018-11-26 14:46:41 -0600150 }
Matt Spinler06a5bdd2018-11-26 14:50:48 -0600151
152 try
153 {
Matt Spinler69f93512018-11-26 14:55:58 -0600154 if (!getService(ID_DBUS_OBJECT_NAME, idButtonIface).empty())
155 {
George Liu9fb15972022-06-20 14:54:38 +0800156 lg2::info("Registering ID button handler");
Matt Spinler69f93512018-11-26 14:55:58 -0600157 idButtonReleased = std::make_unique<sdbusplus::bus::match_t>(
158 bus,
159 sdbusRule::type::signal() + sdbusRule::member("Released") +
160 sdbusRule::path(ID_DBUS_OBJECT_NAME) +
161 sdbusRule::interface(idButtonIface),
Naveen Mosesab8dac52022-07-15 19:32:27 +0530162 std::bind(std::mem_fn(&Handler::idReleased), this,
Matt Spinler69f93512018-11-26 14:55:58 -0600163 std::placeholders::_1));
164 }
165 }
Patrick Williams9a529a62022-07-22 19:26:54 -0500166 catch (const sdbusplus::exception_t& e)
Matt Spinler69f93512018-11-26 14:55:58 -0600167 {
168 // The button wasn't implemented
169 }
170
171 try
172 {
Matt Spinler06a5bdd2018-11-26 14:50:48 -0600173 if (!getService(RESET_DBUS_OBJECT_NAME, resetButtonIface).empty())
174 {
George Liu9fb15972022-06-20 14:54:38 +0800175 lg2::info("Registering reset button handler");
Matt Spinler06a5bdd2018-11-26 14:50:48 -0600176 resetButtonReleased = std::make_unique<sdbusplus::bus::match_t>(
177 bus,
178 sdbusRule::type::signal() + sdbusRule::member("Released") +
179 sdbusRule::path(RESET_DBUS_OBJECT_NAME) +
180 sdbusRule::interface(resetButtonIface),
Naveen Mosesab8dac52022-07-15 19:32:27 +0530181 std::bind(std::mem_fn(&Handler::resetReleased), this,
Matt Spinler06a5bdd2018-11-26 14:50:48 -0600182 std::placeholders::_1));
183 }
184 }
Patrick Williams9a529a62022-07-22 19:26:54 -0500185 catch (const sdbusplus::exception_t& e)
Matt Spinler06a5bdd2018-11-26 14:50:48 -0600186 {
187 // The button wasn't implemented
188 }
Naveen Mosesa6d4e652022-04-13 19:27:25 +0530189 try
190 {
191 if (!getService(DBG_HS_DBUS_OBJECT_NAME, debugHostSelectorIface)
192 .empty())
193 {
194 lg2::info("Registering debug host selector button handler");
195 debugHSButtonReleased = std::make_unique<sdbusplus::bus::match_t>(
196 bus,
197 sdbusRule::type::signal() + sdbusRule::member("Released") +
198 sdbusRule::path(DBG_HS_DBUS_OBJECT_NAME) +
199 sdbusRule::interface(debugHostSelectorIface),
200 std::bind(std::mem_fn(&Handler::debugHostSelectorReleased),
201 this, std::placeholders::_1));
202 }
203 }
Patrick Williamse3b4e112022-11-26 09:41:58 -0600204 catch (const sdbusplus::exception_t& e)
Naveen Mosesa6d4e652022-04-13 19:27:25 +0530205 {
206 // The button wasn't implemented
207 }
Matt Spinler963c65f2018-11-26 14:46:41 -0600208}
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530209bool Handler::isMultiHost()
210{
Rush Chen31ce3752024-11-08 14:57:27 +0800211 if (numberOfChassis() != 1)
212 {
213 return true;
214 }
215 else
216 {
217 return (hostSelectButtonMode);
218 }
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530219}
Matt Spinler963c65f2018-11-26 14:46:41 -0600220std::string Handler::getService(const std::string& path,
221 const std::string& interface) const
222{
223 auto method = bus.new_method_call(mapperService, mapperObjPath, mapperIface,
224 "GetObject");
225 method.append(path, std::vector{interface});
Thang Q. Nguyen42507852022-08-12 09:11:35 +0700226 try
227 {
228 auto result = bus.call(method);
229 std::map<std::string, std::vector<std::string>> objectData;
230 result.read(objectData);
231 return objectData.begin()->first;
232 }
Patrick Williamse3b4e112022-11-26 09:41:58 -0600233 catch (const sdbusplus::exception_t& e)
Thang Q. Nguyen42507852022-08-12 09:11:35 +0700234 {
235 return std::string();
236 }
Matt Spinler963c65f2018-11-26 14:46:41 -0600237}
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530238size_t Handler::getHostSelectorValue()
Matt Spinler963c65f2018-11-26 14:46:41 -0600239{
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530240 auto HSService = getService(HS_DBUS_OBJECT_NAME, hostSelectorIface);
241
242 if (HSService.empty())
243 {
Naveen Mosesa6d4e652022-04-13 19:27:25 +0530244 lg2::info("Host selector dbus object not available");
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530245 throw std::invalid_argument("Host selector dbus object not available");
246 }
247
248 try
249 {
250 auto method = bus.new_method_call(
251 HSService.c_str(), HS_DBUS_OBJECT_NAME, propertyIface, "Get");
252 method.append(hostSelectorIface, "Position");
253 auto result = bus.call(method);
254
255 std::variant<size_t> HSPositionVariant;
256 result.read(HSPositionVariant);
257
258 auto position = std::get<size_t>(HSPositionVariant);
259 return position;
260 }
Patrick Williams9a529a62022-07-22 19:26:54 -0500261 catch (const sdbusplus::exception_t& e)
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530262 {
Naveen Mosesa6d4e652022-04-13 19:27:25 +0530263 lg2::error("Error reading host selector position: {ERROR}", "ERROR", e);
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530264 throw;
265 }
266}
267bool Handler::poweredOn(size_t hostNumber) const
268{
Potin Laic0fee462022-12-23 14:19:23 +0800269 auto hostObjectName = HOST_STATE_OBJECT_NAME + std::to_string(hostNumber);
270 auto service = getService(hostObjectName.c_str(), hostIface);
271 auto method = bus.new_method_call(service.c_str(), hostObjectName.c_str(),
272 propertyIface, "Get");
273 method.append(hostIface, "CurrentHostState");
Matt Spinler963c65f2018-11-26 14:46:41 -0600274 auto result = bus.call(method);
275
Patrick Williams5ed4cc02020-05-13 17:52:15 -0500276 std::variant<std::string> state;
Matt Spinler963c65f2018-11-26 14:46:41 -0600277 result.read(state);
278
Potin Laic0fee462022-12-23 14:19:23 +0800279 return Host::HostState::Off !=
280 Host::convertHostStateFromString(std::get<std::string>(state));
Matt Spinler963c65f2018-11-26 14:46:41 -0600281}
282
DelphineCCChiu395c7642023-04-19 10:46:47 +0800283void Handler::handlePowerEvent(PowerEvent powerEventType,
Rush Chen31ce3752024-11-08 14:57:27 +0800284 const std::string& objectPath,
DelphineCCChiu395c7642023-04-19 10:46:47 +0800285 std::chrono::microseconds duration)
Matt Spinler963c65f2018-11-26 14:46:41 -0600286{
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530287 std::string objPathName;
288 std::string dbusIfaceName;
289 std::string transitionName;
290 std::variant<Host::Transition, Chassis::Transition> transition;
Matt Spinler963c65f2018-11-26 14:46:41 -0600291
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530292 size_t hostNumber = 0;
Rush Chen31ce3752024-11-08 14:57:27 +0800293 std::string hostNumStr =
294 objectPath.substr(std::string(POWER_DBUS_OBJECT_NAME).length());
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530295 auto isMultiHostSystem = isMultiHost();
Rush Chen31ce3752024-11-08 14:57:27 +0800296
297 if (hostSelectButtonMode)
Matt Spinler963c65f2018-11-26 14:46:41 -0600298 {
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530299 hostNumber = getHostSelectorValue();
Naveen Mosesa6d4e652022-04-13 19:27:25 +0530300 lg2::info("Multi-host system detected : {POSITION}", "POSITION",
George Liu9fb15972022-06-20 14:54:38 +0800301 hostNumber);
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530302
Rush Chen31ce3752024-11-08 14:57:27 +0800303 hostNumStr = std::to_string(hostNumber);
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530304
Rush Chen31ce3752024-11-08 14:57:27 +0800305 // ignore power and reset button events if BMC is selected.
306 if (isMultiHostSystem && (hostNumber == BMC_POSITION) &&
307 (powerEventType != PowerEvent::powerReleased) &&
308 (duration <= LONG_PRESS_TIME_MS))
309 {
310 lg2::info(
311 "handlePowerEvent : BMC selected on multi-host system. ignoring power and reset button events...");
312 return;
313 }
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530314 }
315
316 switch (powerEventType)
317 {
Naveen Mosesab8dac52022-07-15 19:32:27 +0530318 case PowerEvent::powerReleased:
George Liu5b98f4d2022-06-20 13:31:14 +0800319 {
Rush Chen31ce3752024-11-08 14:57:27 +0800320 for (const auto& iter : multiPwrBtnActConf[stoi(hostNumStr) - 1])
321 {
322 if (duration > std::chrono::milliseconds(iter.first))
323 {
324 dbusIfaceName = chassisIface;
325 transitionName = "RequestedPowerTransition";
326 objPathName = CHASSIS_STATE_OBJECT_NAME + hostNumStr;
327 transition = iter.second;
328 }
329 }
330 break;
331
Patrick Williams971312a2024-04-12 13:45:50 -0500332 if (duration <= LONG_PRESS_TIME_MS)
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530333 {
DelphineCCChiu395c7642023-04-19 10:46:47 +0800334 objPathName = HOST_STATE_OBJECT_NAME + hostNumStr;
335 dbusIfaceName = hostIface;
336 transitionName = "RequestedHostTransition";
337
338 transition = Host::Transition::On;
339
340 if (poweredOn(hostNumber))
341 {
342 transition = Host::Transition::Off;
343 }
344 lg2::info("handlePowerEvent : Handle power button press ");
DelphineCCChiu395c7642023-04-19 10:46:47 +0800345 break;
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530346 }
DelphineCCChiu395c7642023-04-19 10:46:47 +0800347 else
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530348 {
DelphineCCChiu395c7642023-04-19 10:46:47 +0800349 dbusIfaceName = chassisIface;
350 transitionName = "RequestedPowerTransition";
351 objPathName = CHASSIS_STATE_OBJECT_NAME + hostNumStr;
352 transition = Chassis::Transition::Off;
353
354 /* multi host system :
355 hosts (1 to N) - host shutdown
356 bmc (0) - sled cycle
357 single host system :
358 host(0) - host shutdown
359 */
360 if (isMultiHostSystem && (hostNumber == BMC_POSITION))
361 {
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530362#if CHASSIS_SYSTEM_RESET_ENABLED
DelphineCCChiu395c7642023-04-19 10:46:47 +0800363 objPathName = CHASSISSYSTEM_STATE_OBJECT_NAME + hostNumStr;
364 transition = Chassis::Transition::PowerCycle;
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530365#else
DelphineCCChiu395c7642023-04-19 10:46:47 +0800366 return;
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530367#endif
DelphineCCChiu395c7642023-04-19 10:46:47 +0800368 }
369 else if (!poweredOn(hostNumber))
370 {
371 lg2::info(
372 "Power is off so ignoring long power button press");
373 return;
374 }
375 lg2::info("handlePowerEvent : handle long power button press");
376 break;
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530377 }
Matt Spinler963c65f2018-11-26 14:46:41 -0600378 }
Naveen Mosesab8dac52022-07-15 19:32:27 +0530379 case PowerEvent::resetReleased:
George Liu5b98f4d2022-06-20 13:31:14 +0800380 {
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530381 objPathName = HOST_STATE_OBJECT_NAME + hostNumStr;
382 dbusIfaceName = hostIface;
383 transitionName = "RequestedHostTransition";
Matt Spinler963c65f2018-11-26 14:46:41 -0600384
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530385 if (!poweredOn(hostNumber))
386 {
George Liu9fb15972022-06-20 14:54:38 +0800387 lg2::info("Power is off so ignoring reset button press");
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530388 return;
389 }
Matt Spinler963c65f2018-11-26 14:46:41 -0600390
George Liu9fb15972022-06-20 14:54:38 +0800391 lg2::info("Handling reset button press");
HuyLe9456ffc2023-06-22 15:21:22 +0700392#ifdef ENABLE_RESET_BUTTON_DO_WARM_REBOOT
393 transition = Host::Transition::ForceWarmReboot;
394#else
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530395 transition = Host::Transition::Reboot;
HuyLe9456ffc2023-06-22 15:21:22 +0700396#endif
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530397 break;
398 }
George Liu5b98f4d2022-06-20 13:31:14 +0800399 default:
400 {
George Liu9fb15972022-06-20 14:54:38 +0800401 lg2::error("{EVENT} is invalid power event. skipping...", "EVENT",
Patrick Williams36106082024-02-26 10:26:43 -0600402 powerEventType);
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530403
404 return;
405 }
406 }
407 auto service = getService(objPathName.c_str(), dbusIfaceName);
408 auto method = bus.new_method_call(service.c_str(), objPathName.c_str(),
409 propertyIface, "Set");
410 method.append(dbusIfaceName, transitionName, transition);
411 bus.call(method);
412}
Rush Chen31ce3752024-11-08 14:57:27 +0800413
DelphineCCChiu395c7642023-04-19 10:46:47 +0800414void Handler::powerReleased(sdbusplus::message_t& msg)
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530415{
416 try
417 {
DelphineCCChiu395c7642023-04-19 10:46:47 +0800418 uint64_t time;
419 msg.read(time);
420
Rush Chen31ce3752024-11-08 14:57:27 +0800421 handlePowerEvent(PowerEvent::powerReleased, msg.get_path(),
DelphineCCChiu395c7642023-04-19 10:46:47 +0800422 std::chrono::microseconds(time));
Matt Spinler963c65f2018-11-26 14:46:41 -0600423 }
Patrick Williams9a529a62022-07-22 19:26:54 -0500424 catch (const sdbusplus::exception_t& e)
Matt Spinler963c65f2018-11-26 14:46:41 -0600425 {
George Liu9fb15972022-06-20 14:54:38 +0800426 lg2::error("Failed power state change on a power button press: {ERROR}",
427 "ERROR", e);
Matt Spinler963c65f2018-11-26 14:46:41 -0600428 }
429}
Matt Spinler06a5bdd2018-11-26 14:50:48 -0600430
Rush Chen31ce3752024-11-08 14:57:27 +0800431void Handler::resetReleased(sdbusplus::message_t& msg)
Matt Spinler06a5bdd2018-11-26 14:50:48 -0600432{
433 try
434 {
DelphineCCChiu395c7642023-04-19 10:46:47 +0800435 // No need to calculate duration, set to 0.
Rush Chen31ce3752024-11-08 14:57:27 +0800436 handlePowerEvent(PowerEvent::resetReleased, msg.get_path(),
DelphineCCChiu395c7642023-04-19 10:46:47 +0800437 std::chrono::microseconds(0));
Matt Spinler06a5bdd2018-11-26 14:50:48 -0600438 }
Patrick Williams9a529a62022-07-22 19:26:54 -0500439 catch (const sdbusplus::exception_t& e)
Matt Spinler06a5bdd2018-11-26 14:50:48 -0600440 {
George Liu9fb15972022-06-20 14:54:38 +0800441 lg2::error("Failed power state change on a reset button press: {ERROR}",
442 "ERROR", e);
Matt Spinler06a5bdd2018-11-26 14:50:48 -0600443 }
444}
Matt Spinler69f93512018-11-26 14:55:58 -0600445
Patrick Williams9a529a62022-07-22 19:26:54 -0500446void Handler::idReleased(sdbusplus::message_t& /* msg */)
Matt Spinler69f93512018-11-26 14:55:58 -0600447{
448 std::string groupPath{ledGroupBasePath};
449 groupPath += ID_LED_GROUP;
450
451 auto service = getService(groupPath, ledGroupIface);
452
453 if (service.empty())
454 {
George Liu9fb15972022-06-20 14:54:38 +0800455 lg2::info("No found {GROUP} during ID button press:", "GROUP",
456 groupPath);
Matt Spinler69f93512018-11-26 14:55:58 -0600457 return;
458 }
459
460 try
461 {
462 auto method = bus.new_method_call(service.c_str(), groupPath.c_str(),
463 propertyIface, "Get");
464 method.append(ledGroupIface, "Asserted");
465 auto result = bus.call(method);
466
Patrick Williams5ed4cc02020-05-13 17:52:15 -0500467 std::variant<bool> state;
Matt Spinler69f93512018-11-26 14:55:58 -0600468 result.read(state);
469
Patrick Williams51f5e8b2020-05-13 11:33:44 -0500470 state = !std::get<bool>(state);
Matt Spinler69f93512018-11-26 14:55:58 -0600471
George Liu9fb15972022-06-20 14:54:38 +0800472 lg2::info(
473 "Changing ID LED group state on ID LED press, GROUP = {GROUP}, STATE = {STATE}",
474 "GROUP", groupPath, "STATE", std::get<bool>(state));
Matt Spinler69f93512018-11-26 14:55:58 -0600475
476 method = bus.new_method_call(service.c_str(), groupPath.c_str(),
477 propertyIface, "Set");
478
479 method.append(ledGroupIface, "Asserted", state);
480 result = bus.call(method);
481 }
Patrick Williams9a529a62022-07-22 19:26:54 -0500482 catch (const sdbusplus::exception_t& e)
Matt Spinler69f93512018-11-26 14:55:58 -0600483 {
George Liu9fb15972022-06-20 14:54:38 +0800484 lg2::error("Error toggling ID LED group on ID button press: {ERROR}",
485 "ERROR", e);
Matt Spinler69f93512018-11-26 14:55:58 -0600486 }
487}
Naveen Mosesa6d4e652022-04-13 19:27:25 +0530488
489void Handler::increaseHostSelectorPosition()
490{
491 try
492 {
493 auto HSService = getService(HS_DBUS_OBJECT_NAME, hostSelectorIface);
494
495 if (HSService.empty())
496 {
497 lg2::error("Host selector service not available");
498 return;
499 }
500
501 auto method =
502 bus.new_method_call(HSService.c_str(), HS_DBUS_OBJECT_NAME,
503 phosphor::button::propertyIface, "GetAll");
504 method.append(phosphor::button::hostSelectorIface);
505 auto result = bus.call(method);
506 std::unordered_map<std::string, std::variant<size_t>> properties;
507 result.read(properties);
508
509 auto maxPosition = std::get<size_t>(properties.at("MaxPosition"));
510 auto position = std::get<size_t>(properties.at("Position"));
511
512 std::variant<size_t> HSPositionVariant =
513 (position < maxPosition) ? (position + 1) : 0;
514
515 method = bus.new_method_call(HSService.c_str(), HS_DBUS_OBJECT_NAME,
516 phosphor::button::propertyIface, "Set");
517 method.append(phosphor::button::hostSelectorIface, "Position");
518
519 method.append(HSPositionVariant);
520 result = bus.call(method);
521 }
Patrick Williamse3b4e112022-11-26 09:41:58 -0600522 catch (const sdbusplus::exception_t& e)
Naveen Mosesa6d4e652022-04-13 19:27:25 +0530523 {
524 lg2::error("Error modifying host selector position : {ERROR}", "ERROR",
525 e);
526 }
527}
528
Patrick Williamse3b4e112022-11-26 09:41:58 -0600529void Handler::debugHostSelectorReleased(sdbusplus::message_t& /* msg */)
Naveen Mosesa6d4e652022-04-13 19:27:25 +0530530{
531 try
532 {
533 increaseHostSelectorPosition();
534 }
Patrick Williamse3b4e112022-11-26 09:41:58 -0600535 catch (const sdbusplus::exception_t& e)
Naveen Mosesa6d4e652022-04-13 19:27:25 +0530536 {
537 lg2::error(
538 "Failed power process debug host selector button press : {ERROR}",
539 "ERROR", e);
540 }
541}
542
Matt Spinlerfb35a322018-11-26 14:30:30 -0600543} // namespace button
544} // namespace phosphor