blob: 1af5b280a0cb77e7b10b7262c5d16f310ad48902 [file] [log] [blame]
Yuan Li60e7aaf2019-05-28 14:22:40 +08001/*
2// Copyright (c) 2019 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16#include "xyz/openbmc_project/Common/error.hpp"
17
18#include <fstream>
Jason M. Billsb08f84e2019-06-10 12:59:42 -070019#include <iostream>
Yuan Li60e7aaf2019-05-28 14:22:40 +080020#include <ipmid/api.hpp>
21#include <ipmid/utils.hpp>
22#include <nlohmann/json.hpp>
23#include <phosphor-logging/elog-errors.hpp>
Jason M. Billsb08f84e2019-06-10 12:59:42 -070024#include <phosphor-logging/log.hpp>
Yuan Li60e7aaf2019-05-28 14:22:40 +080025#include <regex>
26#include <sdbusplus/timer.hpp>
Jason M. Billsb08f84e2019-06-10 12:59:42 -070027#include <stdexcept>
28#include <string_view>
29#include <xyz/openbmc_project/Control/Power/RestorePolicy/server.hpp>
Yuan Li60e7aaf2019-05-28 14:22:40 +080030
Jason M. Billsb08f84e2019-06-10 12:59:42 -070031using namespace phosphor::logging;
32
33namespace ipmi::chassis
Yuan Li60e7aaf2019-05-28 14:22:40 +080034{
Jason M. Billsb08f84e2019-06-10 12:59:42 -070035static constexpr const char* buttonIntf = "xyz.openbmc_project.Chassis.Buttons";
Yuan Li60e7aaf2019-05-28 14:22:40 +080036
Jason M. Billsb08f84e2019-06-10 12:59:42 -070037const static constexpr char* idButtonPath =
38 "/xyz/openbmc_project/chassis/buttons/id";
39static constexpr const char* powerButtonPath =
40 "/xyz/openbmc_project/chassis/buttons/power";
41static constexpr const char* resetButtonPath =
42 "/xyz/openbmc_project/chassis/buttons/reset";
43static constexpr const char* interruptButtonPath =
44 "/xyz/openbmc_project/chassis/buttons/nmi";
45
46const static constexpr char* idButtonProp = "ButtonPressed";
47
48const static constexpr char* ledService =
Yuan Li60e7aaf2019-05-28 14:22:40 +080049 "xyz.openbmc_project.LED.GroupManager";
Jason M. Billsb08f84e2019-06-10 12:59:42 -070050const static constexpr char* ledIDOnObj =
Yuan Li60e7aaf2019-05-28 14:22:40 +080051 "/xyz/openbmc_project/led/groups/enclosure_identify";
Jason M. Billsb08f84e2019-06-10 12:59:42 -070052const static constexpr char* ledIDBlinkObj =
Yuan Li60e7aaf2019-05-28 14:22:40 +080053 "/xyz/openbmc_project/led/groups/enclosure_identify_blink";
Jason M. Billsb08f84e2019-06-10 12:59:42 -070054const static constexpr char* ledInterface = "xyz.openbmc_project.Led.Group";
55const static constexpr char* ledProp = "Asserted";
Jason M. Bills09221d72019-07-26 13:38:28 -070056enum class ChassisIDState
57{
58 off = 0,
59 temporary = 1,
60 indefinite = 2,
61};
62static ChassisIDState chassisIDState = ChassisIDState::off;
Yuan Li60e7aaf2019-05-28 14:22:40 +080063
64constexpr size_t defaultIdentifyTimeOut = 15;
65
66std::unique_ptr<phosphor::Timer> identifyTimer
67 __attribute__((init_priority(101)));
68std::unique_ptr<sdbusplus::bus::match_t> matchPtr
69 __attribute__((init_priority(101)));
70
71static void registerChassisFunctions() __attribute__((constructor));
72
73static ipmi::ServiceCache LEDService(ledInterface, ledIDBlinkObj);
74
Jason M. Billsb08f84e2019-06-10 12:59:42 -070075void enclosureIdentifyLed(const char* objName, bool isIdLedOn)
Yuan Li60e7aaf2019-05-28 14:22:40 +080076{
77 auto bus = getSdBus();
78
79 try
80 {
81 std::string service = LEDService.getService(*bus);
82 setDbusProperty(*bus, service, objName, ledInterface, ledProp,
83 isIdLedOn);
84 }
Jason M. Billsb08f84e2019-06-10 12:59:42 -070085 catch (const std::exception& e)
Yuan Li60e7aaf2019-05-28 14:22:40 +080086 {
Jason M. Billsb08f84e2019-06-10 12:59:42 -070087 log<level::ERR>("enclosureIdentifyLed: can't set property",
88 entry("ERR=%s", e.what()));
Yuan Li60e7aaf2019-05-28 14:22:40 +080089 }
90}
91
Jason M. Billsb08f84e2019-06-10 12:59:42 -070092bool getIDState(const char* objName, bool& state)
Yuan Li60e7aaf2019-05-28 14:22:40 +080093{
94 auto bus = getSdBus();
95
96 try
97 {
98 std::string service = LEDService.getService(*bus);
99 ipmi::Value enabled =
100 getDbusProperty(*bus, service, objName, ledInterface, ledProp);
101 state = std::get<bool>(enabled);
102 }
Jason M. Billsb08f84e2019-06-10 12:59:42 -0700103 catch (sdbusplus::exception::SdBusError& e)
Yuan Li60e7aaf2019-05-28 14:22:40 +0800104 {
Jason M. Billsb08f84e2019-06-10 12:59:42 -0700105 log<level::ERR>("Fail to get property", entry("PATH=%s", objName),
106 entry("ERROR=%s", e.what()));
Yuan Li60e7aaf2019-05-28 14:22:40 +0800107 return false;
108 }
109 return true;
110}
111
112void enclosureIdentifyLedBlinkOff()
113{
Jason M. Bills09221d72019-07-26 13:38:28 -0700114 chassisIDState = ChassisIDState::off;
Yuan Li60e7aaf2019-05-28 14:22:40 +0800115 enclosureIdentifyLed(ledIDBlinkObj, false);
116}
117
Jason M. Billsb08f84e2019-06-10 12:59:42 -0700118void idButtonPropChanged(sdbusplus::message::message& msg)
Yuan Li60e7aaf2019-05-28 14:22:40 +0800119{
120 bool asserted = false;
121 bool buttonPressed = false;
122
123 std::map<std::string, ipmi::Value> props;
124 std::vector<std::string> inval;
125 std::string iface;
126 msg.read(iface, props, inval);
127
Jason M. Billsb08f84e2019-06-10 12:59:42 -0700128 for (const auto& t : props)
Yuan Li60e7aaf2019-05-28 14:22:40 +0800129 {
130 auto key = t.first;
131 auto value = t.second;
132
133 if (key == idButtonProp)
134 {
135 buttonPressed = std::get<bool>(value);
136 }
137 break;
138 }
139
140 if (buttonPressed)
141 {
142 if (identifyTimer->isRunning())
143 {
Jason M. Billsb08f84e2019-06-10 12:59:42 -0700144 log<level::INFO>("ID timer is running");
Yuan Li60e7aaf2019-05-28 14:22:40 +0800145 }
146
147 // make sure timer is stopped
148 identifyTimer->stop();
149
150 if (!getIDState(ledIDBlinkObj, asserted))
151 {
152 return;
153 }
154
155 if (asserted)
156 {
157 // LED is blinking, turn off the LED
Jason M. Bills09221d72019-07-26 13:38:28 -0700158 chassisIDState = ChassisIDState::off;
Yuan Li60e7aaf2019-05-28 14:22:40 +0800159 enclosureIdentifyLed(ledIDBlinkObj, false);
160 enclosureIdentifyLed(ledIDOnObj, false);
161 }
162 else
163 {
164 // toggle the IED on/off
165 if (!getIDState(ledIDOnObj, asserted))
166 {
167 return;
168 }
169 enclosureIdentifyLed(ledIDOnObj, !asserted);
170 }
171 }
172}
173
174void createIdentifyTimer()
175{
176 if (!identifyTimer)
177 {
178 identifyTimer =
179 std::make_unique<phosphor::Timer>(enclosureIdentifyLedBlinkOff);
180 }
181}
182
183ipmi::RspType<> ipmiChassisIdentify(std::optional<uint8_t> interval,
184 std::optional<uint8_t> force)
185{
186 uint8_t identifyInterval = interval.value_or(defaultIdentifyTimeOut);
187 bool forceIdentify = force.value_or(0) & 0x01;
188
189 enclosureIdentifyLed(ledIDOnObj, false);
190 identifyTimer->stop();
191
192 if (identifyInterval || forceIdentify)
193 {
194 enclosureIdentifyLed(ledIDBlinkObj, true);
195 if (forceIdentify)
196 {
Jason M. Bills09221d72019-07-26 13:38:28 -0700197 chassisIDState = ChassisIDState::indefinite;
Yuan Li60e7aaf2019-05-28 14:22:40 +0800198 return ipmi::responseSuccess();
199 }
Jason M. Bills09221d72019-07-26 13:38:28 -0700200 chassisIDState = ChassisIDState::temporary;
Yuan Li60e7aaf2019-05-28 14:22:40 +0800201 // start the timer
202 auto time = std::chrono::duration_cast<std::chrono::microseconds>(
203 std::chrono::seconds(identifyInterval));
204 identifyTimer->start(time);
205 }
206 else
207 {
Jason M. Bills09221d72019-07-26 13:38:28 -0700208 chassisIDState = ChassisIDState::off;
Yuan Li60e7aaf2019-05-28 14:22:40 +0800209 enclosureIdentifyLed(ledIDBlinkObj, false);
210 }
211 return ipmi::responseSuccess();
212}
213
Jason M. Billsb08f84e2019-06-10 12:59:42 -0700214namespace power_policy
215{
216/* helper function for Get Chassis Status Command
217 */
218std::optional<uint2_t> getPowerRestorePolicy()
219{
220 constexpr const char* powerRestorePath =
221 "/xyz/openbmc_project/control/host0/power_restore_policy";
222 constexpr const char* powerRestoreIntf =
223 "xyz.openbmc_project.Control.Power.RestorePolicy";
224 uint2_t restorePolicy = 0;
225 std::shared_ptr<sdbusplus::asio::connection> busp = getSdBus();
226
227 try
228 {
229 auto service =
230 ipmi::getService(*busp, powerRestoreIntf, powerRestorePath);
231
232 ipmi::Value result =
233 ipmi::getDbusProperty(*busp, service, powerRestorePath,
234 powerRestoreIntf, "PowerRestorePolicy");
235 auto powerRestore = sdbusplus::xyz::openbmc_project::Control::Power::
236 server::RestorePolicy::convertPolicyFromString(
237 std::get<std::string>(result));
238
239 using namespace sdbusplus::xyz::openbmc_project::Control::Power::server;
240 switch (powerRestore)
241 {
242 case RestorePolicy::Policy::AlwaysOff:
243 restorePolicy = 0x00;
244 break;
245 case RestorePolicy::Policy::Restore:
246 restorePolicy = 0x01;
247 break;
248 case RestorePolicy::Policy::AlwaysOn:
249 restorePolicy = 0x02;
250 break;
251 }
252 }
253 catch (const std::exception& e)
254 {
255 log<level::ERR>("Failed to fetch PowerRestorePolicy property",
256 entry("ERROR=%s", e.what()),
257 entry("PATH=%s", powerRestorePath),
258 entry("INTERFACE=%s", powerRestoreIntf));
259 return std::nullopt;
260 }
261 return std::make_optional(restorePolicy);
262}
263
264/*
265 * getPowerStatus
266 * helper function for Get Chassis Status Command
267 * return - optional value for pgood (no value on error)
268 */
269std::optional<bool> getPowerStatus()
270{
271 bool powerGood = false;
272 std::shared_ptr<sdbusplus::asio::connection> busp = getSdBus();
273 try
274 {
275 constexpr const char* chassisStatePath =
276 "/xyz/openbmc_project/state/chassis0";
277 constexpr const char* chassisStateIntf =
278 "xyz.openbmc_project.State.Chassis";
279 auto service =
280 ipmi::getService(*busp, chassisStateIntf, chassisStatePath);
281
282 ipmi::Value variant =
283 ipmi::getDbusProperty(*busp, service, chassisStatePath,
284 chassisStateIntf, "CurrentPowerState");
285 std::string powerState = std::get<std::string>(variant);
286 if (powerState == "xyz.openbmc_project.State.Chassis.PowerState.On")
287 {
288 powerGood = true;
289 }
290 }
291 catch (const std::exception& e)
292 {
293 log<level::ERR>("Failed to fetch power state property",
294 entry("ERROR=%s", e.what()));
295 return std::nullopt;
296 }
297 return std::make_optional(powerGood);
298}
299
300/*
301 * getACFailStatus
302 * helper function for Get Chassis Status Command
303 * return - bool value for ACFail (false on error)
304 */
305bool getACFailStatus()
306{
Jason M. Billsa2b4c7a2019-06-24 16:55:21 -0700307 constexpr const char* acBootObj =
308 "/xyz/openbmc_project/control/host0/ac_boot";
309 constexpr const char* acBootIntf = "xyz.openbmc_project.Common.ACBoot";
310 std::string acFail;
Jason M. Billsb08f84e2019-06-10 12:59:42 -0700311 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
312 try
313 {
Jason M. Billsa2b4c7a2019-06-24 16:55:21 -0700314 auto service = ipmi::getService(*bus, acBootIntf, acBootObj);
Jason M. Billsb08f84e2019-06-10 12:59:42 -0700315
Jason M. Billsa2b4c7a2019-06-24 16:55:21 -0700316 ipmi::Value variant = ipmi::getDbusProperty(*bus, service, acBootObj,
317 acBootIntf, "ACBoot");
318 acFail = std::get<std::string>(variant);
Jason M. Billsb08f84e2019-06-10 12:59:42 -0700319 }
320 catch (const std::exception& e)
321 {
Jason M. Billsa2b4c7a2019-06-24 16:55:21 -0700322 log<level::ERR>(
323 "Failed to fetch ACBoot property", entry("ERROR=%s", e.what()),
324 entry("PATH=%s", acBootObj), entry("INTERFACE=%s", acBootIntf));
Jason M. Billsb08f84e2019-06-10 12:59:42 -0700325 }
Jason M. Billsa2b4c7a2019-06-24 16:55:21 -0700326 return acFail == "True";
Jason M. Billsb08f84e2019-06-10 12:59:42 -0700327}
328} // namespace power_policy
329
330static std::optional<bool> getButtonEnabled(const std::string& buttonPath)
331{
332 bool buttonDisabled = false;
333 std::shared_ptr<sdbusplus::asio::connection> busp = getSdBus();
334 try
335 {
336 auto service = ipmi::getService(*getSdBus(), buttonIntf, buttonPath);
337 ipmi::Value disabled = ipmi::getDbusProperty(
338 *busp, service, buttonPath, buttonIntf, "ButtonMasked");
339 buttonDisabled = std::get<bool>(disabled);
340 }
341 catch (sdbusplus::exception::SdBusError& e)
342 {
343 log<level::ERR>("Fail to get button disabled property",
344 entry("PATH=%s", buttonPath.c_str()),
345 entry("ERROR=%s", e.what()));
346 return std::nullopt;
347 }
348 return std::make_optional(buttonDisabled);
349}
350
351static bool setButtonEnabled(const std::string& buttonPath, const bool disabled)
352{
353 try
354 {
355 auto service = ipmi::getService(*getSdBus(), buttonIntf, buttonPath);
356 ipmi::setDbusProperty(*getSdBus(), service, buttonPath, buttonIntf,
357 "ButtonMasked", disabled);
358 }
359 catch (std::exception& e)
360 {
361 log<level::ERR>("Failed to set button disabled",
362 entry("EXCEPTION=%s, REQUEST=%x", e.what(), disabled));
363 return -1;
364 }
365
366 return 0;
367}
368
369//----------------------------------------------------------------------
370// Get Chassis Status commands
371//----------------------------------------------------------------------
372ipmi::RspType<bool, // Power is on
373 bool, // Power overload
374 bool, // Interlock
375 bool, // power fault
376 bool, // power control fault
377 uint2_t, // power restore policy
378 bool, // reserved
379
380 bool, // AC failed
381 bool, // last power down caused by a Power overload
382 bool, // last power down caused by a power interlock
383 bool, // last power down caused by power fault
384 bool, // last ‘Power is on’ state was entered via IPMI command
385 uint3_t, // reserved
386
387 bool, // Chassis intrusion active
388 bool, // Front Panel Lockout active
389 bool, // Drive Fault
390 bool, // Cooling/fan fault detected
391 uint2_t, // Chassis Identify State
392 bool, // Chassis Identify command and state info supported
393 bool, // reserved
394
395 bool, // Power off button disabled
396 bool, // Reset button disabled
397 bool, // Diagnostic Interrupt button disabled
398 bool, // Standby (sleep) button disabled
399 bool, // Power off button disable allowed
400 bool, // Reset button disable allowed
401 bool, // Diagnostic Interrupt button disable allowed
402 bool // Standby (sleep) button disable allowed
403 >
404 ipmiGetChassisStatus()
405{
406 std::optional<uint2_t> restorePolicy =
407 power_policy::getPowerRestorePolicy();
408 std::optional<bool> powerGood = power_policy::getPowerStatus();
409 if (!restorePolicy || !powerGood)
410 {
411 return ipmi::responseUnspecifiedError();
412 }
413
414 // Front Panel Button Capabilities and disable/enable status(Optional)
415 std::optional<bool> powerButtonReading = getButtonEnabled(powerButtonPath);
416 // allow disable if the interface is present
417 bool powerButtonDisableAllow = static_cast<bool>(powerButtonReading);
418 // default return the button is enabled (not disabled)
419 bool powerButtonDisabled = false;
420 if (powerButtonDisableAllow)
421 {
422 // return the real value of the button status, if present
423 powerButtonDisabled = *powerButtonReading;
424 }
425
426 std::optional<bool> resetButtonReading = getButtonEnabled(resetButtonPath);
427 // allow disable if the interface is present
428 bool resetButtonDisableAllow = static_cast<bool>(resetButtonReading);
429 // default return the button is enabled (not disabled)
430 bool resetButtonDisabled = false;
431 if (resetButtonDisableAllow)
432 {
433 // return the real value of the button status, if present
434 resetButtonDisabled = *resetButtonReading;
435 }
436
437 std::optional<bool> interruptButtonReading =
438 getButtonEnabled(interruptButtonPath);
439 // allow disable if the interface is present
440 bool interruptButtonDisableAllow =
441 static_cast<bool>(interruptButtonReading);
442 // default return the button is enabled (not disabled)
443 bool interruptButtonDisabled = false;
444 if (interruptButtonDisableAllow)
445 {
446 // return the real value of the button status, if present
447 interruptButtonDisabled = *interruptButtonReading;
448 }
449
450 bool powerDownAcFailed = power_policy::getACFailStatus();
451
452 // This response has a lot of hard-coded, unsupported fields
453 // They are set to false or 0
454 constexpr bool powerOverload = false;
455 constexpr bool chassisInterlock = false;
456 constexpr bool powerFault = false;
457 constexpr bool powerControlFault = false;
458 constexpr bool powerDownOverload = false;
459 constexpr bool powerDownInterlock = false;
460 constexpr bool powerDownPowerFault = false;
461 constexpr bool powerStatusIPMI = false;
462 constexpr bool chassisIntrusionActive = false;
463 constexpr bool frontPanelLockoutActive = false;
464 constexpr bool driveFault = false;
465 constexpr bool coolingFanFault = false;
466 // chassisIdentifySupport set because this command is implemented
467 constexpr bool chassisIdentifySupport = true;
Jason M. Bills09221d72019-07-26 13:38:28 -0700468 uint2_t chassisIdentifyState = chassisIDState;
Jason M. Billsb08f84e2019-06-10 12:59:42 -0700469 constexpr bool sleepButtonDisabled = false;
470 constexpr bool sleepButtonDisableAllow = false;
471
472 return ipmi::responseSuccess(
473 *powerGood, powerOverload, chassisInterlock, powerFault,
474 powerControlFault, *restorePolicy,
475 false, // reserved
476
477 powerDownAcFailed, powerDownOverload, powerDownInterlock,
478 powerDownPowerFault, powerStatusIPMI,
479 uint3_t(0), // reserved
480
481 chassisIntrusionActive, frontPanelLockoutActive, driveFault,
482 coolingFanFault, chassisIdentifyState, chassisIdentifySupport,
483 false, // reserved
484
485 powerButtonDisabled, resetButtonDisabled, interruptButtonDisabled,
486 sleepButtonDisabled, powerButtonDisableAllow, resetButtonDisableAllow,
487 interruptButtonDisableAllow, sleepButtonDisableAllow);
488}
489
Jason M. Bills3efc6452019-06-20 15:51:47 -0700490static uint4_t getRestartCause(const std::string& cause)
491{
492 uint4_t restartCauseValue = 0;
493 if (cause == "xyz.openbmc_project.State.Host.RestartCause.Unknown")
494 {
495 restartCauseValue = 0x0;
496 }
497 else if (cause == "xyz.openbmc_project.State.Host.RestartCause.IpmiCommand")
498 {
499 restartCauseValue = 0x1;
500 }
501 else if (cause == "xyz.openbmc_project.State.Host.RestartCause.ResetButton")
502 {
503 restartCauseValue = 0x2;
504 }
505 else if (cause == "xyz.openbmc_project.State.Host.RestartCause.PowerButton")
506 {
507 restartCauseValue = 0x3;
508 }
509 else if (cause ==
510 "xyz.openbmc_project.State.Host.RestartCause.WatchdogTimer")
511 {
512 restartCauseValue = 0x4;
513 }
514 else if (cause == "xyz.openbmc_project.State.Host.RestartCause.OEM")
515 {
516 restartCauseValue = 0x5;
517 }
518 else if (cause ==
519 "xyz.openbmc_project.State.Host.RestartCause.PowerPolicyAlwaysOn")
520 {
521 restartCauseValue = 0x6;
522 }
523 else if (cause == "xyz.openbmc_project.State.Host.RestartCause."
524 "PowerPolicyPreviousState")
525 {
526 restartCauseValue = 0x7;
527 }
528 else if (cause == "xyz.openbmc_project.State.Host.RestartCause.PEFReset")
529 {
530 restartCauseValue = 0x8;
531 }
532 else if (cause ==
533 "xyz.openbmc_project.State.Host.RestartCause.PEFPowerCycle")
534 {
535 restartCauseValue = 0x9;
536 }
537 else if (cause == "xyz.openbmc_project.State.Host.RestartCause.SoftReset")
538 {
539 restartCauseValue = 0xa;
540 }
541 else if (cause == "xyz.openbmc_project.State.Host.RestartCause.RTCWakeup")
542 {
543 restartCauseValue = 0xb;
544 }
545 return restartCauseValue;
546}
547
548ipmi::RspType<uint4_t, // Restart Cause
549 uint4_t, // reserved
550 uint8_t // channel number (not supported)
551 >
552 ipmiGetSystemRestartCause()
553{
554 constexpr const char* restartCausePath =
555 "/xyz/openbmc_project/control/host0/restart_cause";
556 constexpr const char* restartCauseIntf =
557 "xyz.openbmc_project.Common.RestartCause";
558 std::string restartCauseStr;
559 std::shared_ptr<sdbusplus::asio::connection> busp = getSdBus();
560
561 try
562 {
563 auto service =
564 ipmi::getService(*busp, restartCauseIntf, restartCausePath);
565
566 ipmi::Value result = ipmi::getDbusProperty(
567 *busp, service, restartCausePath, restartCauseIntf, "RestartCause");
568 restartCauseStr = std::get<std::string>(result);
569 }
570 catch (const std::exception& e)
571 {
572 log<level::ERR>("Failed to fetch RestartCause property",
573 entry("ERROR=%s", e.what()),
574 entry("PATH=%s", restartCausePath),
575 entry("INTERFACE=%s", restartCauseIntf));
576 return ipmi::responseUnspecifiedError();
577 }
578
579 return ipmi::responseSuccess(getRestartCause(restartCauseStr), 0, 0);
580}
581
Jason M. Billsb08f84e2019-06-10 12:59:42 -0700582ipmi::RspType<> ipmiSetFrontPanelButtonEnables(bool disablePowerButton,
583 bool disableResetButton,
584 bool disableInterruptButton,
585 bool disableSleepButton,
586 uint4_t reserved)
587{
588 bool error = false;
589
590 error |= setButtonEnabled(powerButtonPath, disablePowerButton);
591 error |= setButtonEnabled(resetButtonPath, disableResetButton);
592 error |= setButtonEnabled(interruptButtonPath, disableInterruptButton);
593
594 if (error)
595 {
596 return ipmi::responseUnspecifiedError();
597 }
598 return ipmi::responseSuccess();
599}
600
Yuan Li60e7aaf2019-05-28 14:22:40 +0800601static void registerChassisFunctions(void)
602{
Jason M. Billsb08f84e2019-06-10 12:59:42 -0700603 log<level::INFO>("Registering Chassis commands");
Yuan Li60e7aaf2019-05-28 14:22:40 +0800604
605 createIdentifyTimer();
606
607 if (matchPtr == nullptr)
608 {
609 using namespace sdbusplus::bus::match::rules;
610 auto bus = getSdBus();
611
612 matchPtr = std::make_unique<sdbusplus::bus::match_t>(
613 *bus,
614 sdbusplus::bus::match::rules::propertiesChanged(idButtonPath,
Jason M. Billsb08f84e2019-06-10 12:59:42 -0700615 buttonIntf),
Yuan Li60e7aaf2019-05-28 14:22:40 +0800616 std::bind(idButtonPropChanged, std::placeholders::_1));
617 }
618
619 // <Chassis Identify>
620 ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnChassis,
621 ipmi::chassis::cmdChassisIdentify,
622 ipmi::Privilege::Operator, ipmiChassisIdentify);
Jason M. Billsb08f84e2019-06-10 12:59:42 -0700623 // <Get Chassis Status>
624 ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnChassis,
625 ipmi::chassis::cmdGetChassisStatus,
626 ipmi::Privilege::User, ipmiGetChassisStatus);
Jason M. Bills3efc6452019-06-20 15:51:47 -0700627 // <Get System Restart Cause>
628 ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnChassis,
629 ipmi::chassis::cmdGetSystemRestartCause,
630 ipmi::Privilege::User, ipmiGetSystemRestartCause);
Jason M. Billsb08f84e2019-06-10 12:59:42 -0700631 // <Set Front Panel Enables>
632 ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnChassis,
633 ipmi::chassis::cmdSetFrontPanelButtonEnables,
634 ipmi::Privilege::User,
635 ipmiSetFrontPanelButtonEnables);
Yuan Li60e7aaf2019-05-28 14:22:40 +0800636}
637
Jason M. Billsb08f84e2019-06-10 12:59:42 -0700638} // namespace ipmi::chassis