blob: ab52c66a198e038ff1e2989db94cf33fda7b0cf6 [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);
Patrick Williams60dc3412025-11-05 00:05:37 -0500229 auto objectData =
230 result.unpack<std::map<std::string, std::vector<std::string>>>();
231
Thang Q. Nguyen42507852022-08-12 09:11:35 +0700232 return objectData.begin()->first;
233 }
Patrick Williamse3b4e112022-11-26 09:41:58 -0600234 catch (const sdbusplus::exception_t& e)
Thang Q. Nguyen42507852022-08-12 09:11:35 +0700235 {
236 return std::string();
237 }
Matt Spinler963c65f2018-11-26 14:46:41 -0600238}
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530239size_t Handler::getHostSelectorValue()
Matt Spinler963c65f2018-11-26 14:46:41 -0600240{
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530241 auto HSService = getService(HS_DBUS_OBJECT_NAME, hostSelectorIface);
242
243 if (HSService.empty())
244 {
Naveen Mosesa6d4e652022-04-13 19:27:25 +0530245 lg2::info("Host selector dbus object not available");
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530246 throw std::invalid_argument("Host selector dbus object not available");
247 }
248
249 try
250 {
251 auto method = bus.new_method_call(
252 HSService.c_str(), HS_DBUS_OBJECT_NAME, propertyIface, "Get");
253 method.append(hostSelectorIface, "Position");
254 auto result = bus.call(method);
255
Patrick Williams60dc3412025-11-05 00:05:37 -0500256 auto HSPositionVariant = result.unpack<std::variant<size_t>>();
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530257
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 Williams60dc3412025-11-05 00:05:37 -0500276 auto state = result.unpack<std::variant<std::string>>();
Matt Spinler963c65f2018-11-26 14:46:41 -0600277
Potin Laic0fee462022-12-23 14:19:23 +0800278 return Host::HostState::Off !=
279 Host::convertHostStateFromString(std::get<std::string>(state));
Matt Spinler963c65f2018-11-26 14:46:41 -0600280}
281
DelphineCCChiu395c7642023-04-19 10:46:47 +0800282void Handler::handlePowerEvent(PowerEvent powerEventType,
Rush Chen31ce3752024-11-08 14:57:27 +0800283 const std::string& objectPath,
DelphineCCChiu395c7642023-04-19 10:46:47 +0800284 std::chrono::microseconds duration)
Matt Spinler963c65f2018-11-26 14:46:41 -0600285{
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530286 std::string objPathName;
287 std::string dbusIfaceName;
288 std::string transitionName;
289 std::variant<Host::Transition, Chassis::Transition> transition;
Matt Spinler963c65f2018-11-26 14:46:41 -0600290
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530291 size_t hostNumber = 0;
Rush Chen31ce3752024-11-08 14:57:27 +0800292 std::string hostNumStr =
293 objectPath.substr(std::string(POWER_DBUS_OBJECT_NAME).length());
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530294 auto isMultiHostSystem = isMultiHost();
Rush Chen31ce3752024-11-08 14:57:27 +0800295
296 if (hostSelectButtonMode)
Matt Spinler963c65f2018-11-26 14:46:41 -0600297 {
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530298 hostNumber = getHostSelectorValue();
Naveen Mosesa6d4e652022-04-13 19:27:25 +0530299 lg2::info("Multi-host system detected : {POSITION}", "POSITION",
George Liu9fb15972022-06-20 14:54:38 +0800300 hostNumber);
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530301
Rush Chen31ce3752024-11-08 14:57:27 +0800302 hostNumStr = std::to_string(hostNumber);
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530303
Rush Chen31ce3752024-11-08 14:57:27 +0800304 // ignore power and reset button events if BMC is selected.
305 if (isMultiHostSystem && (hostNumber == BMC_POSITION) &&
306 (powerEventType != PowerEvent::powerReleased) &&
307 (duration <= LONG_PRESS_TIME_MS))
308 {
309 lg2::info(
310 "handlePowerEvent : BMC selected on multi-host system. ignoring power and reset button events...");
311 return;
312 }
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530313 }
314
315 switch (powerEventType)
316 {
Naveen Mosesab8dac52022-07-15 19:32:27 +0530317 case PowerEvent::powerReleased:
George Liu5b98f4d2022-06-20 13:31:14 +0800318 {
Rush Chen31ce3752024-11-08 14:57:27 +0800319 for (const auto& iter : multiPwrBtnActConf[stoi(hostNumStr) - 1])
320 {
321 if (duration > std::chrono::milliseconds(iter.first))
322 {
323 dbusIfaceName = chassisIface;
324 transitionName = "RequestedPowerTransition";
325 objPathName = CHASSIS_STATE_OBJECT_NAME + hostNumStr;
326 transition = iter.second;
327 }
328 }
329 break;
330
Patrick Williams971312a2024-04-12 13:45:50 -0500331 if (duration <= LONG_PRESS_TIME_MS)
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530332 {
DelphineCCChiu395c7642023-04-19 10:46:47 +0800333 objPathName = HOST_STATE_OBJECT_NAME + hostNumStr;
334 dbusIfaceName = hostIface;
335 transitionName = "RequestedHostTransition";
336
337 transition = Host::Transition::On;
338
339 if (poweredOn(hostNumber))
340 {
341 transition = Host::Transition::Off;
342 }
343 lg2::info("handlePowerEvent : Handle power button press ");
DelphineCCChiu395c7642023-04-19 10:46:47 +0800344 break;
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530345 }
DelphineCCChiu395c7642023-04-19 10:46:47 +0800346 else
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530347 {
DelphineCCChiu395c7642023-04-19 10:46:47 +0800348 dbusIfaceName = chassisIface;
349 transitionName = "RequestedPowerTransition";
350 objPathName = CHASSIS_STATE_OBJECT_NAME + hostNumStr;
351 transition = Chassis::Transition::Off;
352
353 /* multi host system :
354 hosts (1 to N) - host shutdown
355 bmc (0) - sled cycle
356 single host system :
357 host(0) - host shutdown
358 */
359 if (isMultiHostSystem && (hostNumber == BMC_POSITION))
360 {
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530361#if CHASSIS_SYSTEM_RESET_ENABLED
DelphineCCChiu395c7642023-04-19 10:46:47 +0800362 objPathName = CHASSISSYSTEM_STATE_OBJECT_NAME + hostNumStr;
363 transition = Chassis::Transition::PowerCycle;
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530364#else
DelphineCCChiu395c7642023-04-19 10:46:47 +0800365 return;
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530366#endif
DelphineCCChiu395c7642023-04-19 10:46:47 +0800367 }
368 else if (!poweredOn(hostNumber))
369 {
370 lg2::info(
371 "Power is off so ignoring long power button press");
372 return;
373 }
374 lg2::info("handlePowerEvent : handle long power button press");
375 break;
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530376 }
Matt Spinler963c65f2018-11-26 14:46:41 -0600377 }
Naveen Mosesab8dac52022-07-15 19:32:27 +0530378 case PowerEvent::resetReleased:
George Liu5b98f4d2022-06-20 13:31:14 +0800379 {
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530380 objPathName = HOST_STATE_OBJECT_NAME + hostNumStr;
381 dbusIfaceName = hostIface;
382 transitionName = "RequestedHostTransition";
Matt Spinler963c65f2018-11-26 14:46:41 -0600383
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530384 if (!poweredOn(hostNumber))
385 {
George Liu9fb15972022-06-20 14:54:38 +0800386 lg2::info("Power is off so ignoring reset button press");
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530387 return;
388 }
Matt Spinler963c65f2018-11-26 14:46:41 -0600389
George Liu9fb15972022-06-20 14:54:38 +0800390 lg2::info("Handling reset button press");
HuyLe9456ffc2023-06-22 15:21:22 +0700391#ifdef ENABLE_RESET_BUTTON_DO_WARM_REBOOT
392 transition = Host::Transition::ForceWarmReboot;
393#else
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530394 transition = Host::Transition::Reboot;
HuyLe9456ffc2023-06-22 15:21:22 +0700395#endif
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530396 break;
397 }
George Liu5b98f4d2022-06-20 13:31:14 +0800398 default:
399 {
George Liu9fb15972022-06-20 14:54:38 +0800400 lg2::error("{EVENT} is invalid power event. skipping...", "EVENT",
Patrick Williams36106082024-02-26 10:26:43 -0600401 powerEventType);
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530402
403 return;
404 }
405 }
406 auto service = getService(objPathName.c_str(), dbusIfaceName);
407 auto method = bus.new_method_call(service.c_str(), objPathName.c_str(),
408 propertyIface, "Set");
409 method.append(dbusIfaceName, transitionName, transition);
410 bus.call(method);
411}
Rush Chen31ce3752024-11-08 14:57:27 +0800412
DelphineCCChiu395c7642023-04-19 10:46:47 +0800413void Handler::powerReleased(sdbusplus::message_t& msg)
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530414{
415 try
416 {
Patrick Williams60dc3412025-11-05 00:05:37 -0500417 auto time = msg.unpack<uint64_t>();
DelphineCCChiu395c7642023-04-19 10:46:47 +0800418
Rush Chen31ce3752024-11-08 14:57:27 +0800419 handlePowerEvent(PowerEvent::powerReleased, msg.get_path(),
DelphineCCChiu395c7642023-04-19 10:46:47 +0800420 std::chrono::microseconds(time));
Matt Spinler963c65f2018-11-26 14:46:41 -0600421 }
Patrick Williams9a529a62022-07-22 19:26:54 -0500422 catch (const sdbusplus::exception_t& e)
Matt Spinler963c65f2018-11-26 14:46:41 -0600423 {
George Liu9fb15972022-06-20 14:54:38 +0800424 lg2::error("Failed power state change on a power button press: {ERROR}",
425 "ERROR", e);
Matt Spinler963c65f2018-11-26 14:46:41 -0600426 }
427}
Matt Spinler06a5bdd2018-11-26 14:50:48 -0600428
Rush Chen31ce3752024-11-08 14:57:27 +0800429void Handler::resetReleased(sdbusplus::message_t& msg)
Matt Spinler06a5bdd2018-11-26 14:50:48 -0600430{
431 try
432 {
DelphineCCChiu395c7642023-04-19 10:46:47 +0800433 // No need to calculate duration, set to 0.
Rush Chen31ce3752024-11-08 14:57:27 +0800434 handlePowerEvent(PowerEvent::resetReleased, msg.get_path(),
DelphineCCChiu395c7642023-04-19 10:46:47 +0800435 std::chrono::microseconds(0));
Matt Spinler06a5bdd2018-11-26 14:50:48 -0600436 }
Patrick Williams9a529a62022-07-22 19:26:54 -0500437 catch (const sdbusplus::exception_t& e)
Matt Spinler06a5bdd2018-11-26 14:50:48 -0600438 {
George Liu9fb15972022-06-20 14:54:38 +0800439 lg2::error("Failed power state change on a reset button press: {ERROR}",
440 "ERROR", e);
Matt Spinler06a5bdd2018-11-26 14:50:48 -0600441 }
442}
Matt Spinler69f93512018-11-26 14:55:58 -0600443
Patrick Williams9a529a62022-07-22 19:26:54 -0500444void Handler::idReleased(sdbusplus::message_t& /* msg */)
Matt Spinler69f93512018-11-26 14:55:58 -0600445{
446 std::string groupPath{ledGroupBasePath};
447 groupPath += ID_LED_GROUP;
448
449 auto service = getService(groupPath, ledGroupIface);
450
451 if (service.empty())
452 {
George Liu9fb15972022-06-20 14:54:38 +0800453 lg2::info("No found {GROUP} during ID button press:", "GROUP",
454 groupPath);
Matt Spinler69f93512018-11-26 14:55:58 -0600455 return;
456 }
457
458 try
459 {
460 auto method = bus.new_method_call(service.c_str(), groupPath.c_str(),
461 propertyIface, "Get");
462 method.append(ledGroupIface, "Asserted");
463 auto result = bus.call(method);
464
Patrick Williams60dc3412025-11-05 00:05:37 -0500465 auto state = result.unpack<std::variant<bool>>();
Matt Spinler69f93512018-11-26 14:55:58 -0600466
Patrick Williams51f5e8b2020-05-13 11:33:44 -0500467 state = !std::get<bool>(state);
Matt Spinler69f93512018-11-26 14:55:58 -0600468
George Liu9fb15972022-06-20 14:54:38 +0800469 lg2::info(
470 "Changing ID LED group state on ID LED press, GROUP = {GROUP}, STATE = {STATE}",
471 "GROUP", groupPath, "STATE", std::get<bool>(state));
Matt Spinler69f93512018-11-26 14:55:58 -0600472
473 method = bus.new_method_call(service.c_str(), groupPath.c_str(),
474 propertyIface, "Set");
475
476 method.append(ledGroupIface, "Asserted", state);
477 result = bus.call(method);
478 }
Patrick Williams9a529a62022-07-22 19:26:54 -0500479 catch (const sdbusplus::exception_t& e)
Matt Spinler69f93512018-11-26 14:55:58 -0600480 {
George Liu9fb15972022-06-20 14:54:38 +0800481 lg2::error("Error toggling ID LED group on ID button press: {ERROR}",
482 "ERROR", e);
Matt Spinler69f93512018-11-26 14:55:58 -0600483 }
484}
Naveen Mosesa6d4e652022-04-13 19:27:25 +0530485
486void Handler::increaseHostSelectorPosition()
487{
488 try
489 {
490 auto HSService = getService(HS_DBUS_OBJECT_NAME, hostSelectorIface);
491
492 if (HSService.empty())
493 {
494 lg2::error("Host selector service not available");
495 return;
496 }
497
498 auto method =
499 bus.new_method_call(HSService.c_str(), HS_DBUS_OBJECT_NAME,
500 phosphor::button::propertyIface, "GetAll");
501 method.append(phosphor::button::hostSelectorIface);
502 auto result = bus.call(method);
Patrick Williams60dc3412025-11-05 00:05:37 -0500503 auto properties = result.unpack<
504 std::unordered_map<std::string, std::variant<size_t>>>();
Naveen Mosesa6d4e652022-04-13 19:27:25 +0530505
506 auto maxPosition = std::get<size_t>(properties.at("MaxPosition"));
507 auto position = std::get<size_t>(properties.at("Position"));
508
509 std::variant<size_t> HSPositionVariant =
510 (position < maxPosition) ? (position + 1) : 0;
511
512 method = bus.new_method_call(HSService.c_str(), HS_DBUS_OBJECT_NAME,
513 phosphor::button::propertyIface, "Set");
514 method.append(phosphor::button::hostSelectorIface, "Position");
515
516 method.append(HSPositionVariant);
517 result = bus.call(method);
518 }
Patrick Williamse3b4e112022-11-26 09:41:58 -0600519 catch (const sdbusplus::exception_t& e)
Naveen Mosesa6d4e652022-04-13 19:27:25 +0530520 {
521 lg2::error("Error modifying host selector position : {ERROR}", "ERROR",
522 e);
523 }
524}
525
Patrick Williamse3b4e112022-11-26 09:41:58 -0600526void Handler::debugHostSelectorReleased(sdbusplus::message_t& /* msg */)
Naveen Mosesa6d4e652022-04-13 19:27:25 +0530527{
528 try
529 {
530 increaseHostSelectorPosition();
531 }
Patrick Williamse3b4e112022-11-26 09:41:58 -0600532 catch (const sdbusplus::exception_t& e)
Naveen Mosesa6d4e652022-04-13 19:27:25 +0530533 {
534 lg2::error(
535 "Failed power process debug host selector button press : {ERROR}",
536 "ERROR", e);
537 }
538}
539
Matt Spinlerfb35a322018-11-26 14:30:30 -0600540} // namespace button
541} // namespace phosphor