1 #include <functional> 2 #include <systemintfcmds.h> 3 #include <ipmid-host-cmd.hpp> 4 #include <utils.hpp> 5 #include <phosphor-logging/log.hpp> 6 #include <config.h> 7 #include <host-interface.hpp> 8 namespace phosphor 9 { 10 namespace host 11 { 12 namespace command 13 { 14 15 // When you see Base:: you know we're referencing our base class 16 namespace Base = sdbusplus::xyz::openbmc_project::Control::server; 17 18 // IPMI OEM command. 19 // https://github.com/openbmc/openbmc/issues/2082 for handling 20 // Non-OEM commands that need to send SMS_ATN 21 using OEMCmd = uint8_t; 22 23 // Map of IPMI OEM command to its equivalent interface command. 24 // This is needed when invoking the callback handler to indicate 25 // the status of the executed command. 26 static const std::map<OEMCmd, Host::Command> intfCommand = { 27 { 28 CMD_HEARTBEAT, 29 Base::Host::Command::Heartbeat 30 }, 31 { 32 CMD_POWER, 33 Base::Host::Command::SoftOff 34 } 35 }; 36 37 // Map of Interface command to its corresponding IPMI OEM command. 38 // This is needed when pushing IPMI commands to command manager's 39 // queue. The same pair will be returned when IPMI asks us 40 // why a SMS_ATN was sent 41 static const std::map<Host::Command, IpmiCmdData> ipmiCommand = { 42 { 43 Base::Host::Command::Heartbeat, 44 std::make_pair(CMD_HEARTBEAT, 0x00) 45 }, 46 { 47 Base::Host::Command::SoftOff, 48 std::make_pair(CMD_POWER, SOFT_OFF) 49 } 50 }; 51 52 // Called at user request 53 void Host::execute(Base::Host::Command command) 54 { 55 using namespace phosphor::logging; 56 57 log<level::INFO>("Pushing cmd on to queue", 58 entry("CONTROL_HOST_CMD=%s", 59 convertForMessage(command))); 60 61 auto cmd = std::make_tuple(ipmiCommand.at(command), 62 std::bind(&Host::commandStatusHandler, 63 this, std::placeholders::_1, 64 std::placeholders::_2)); 65 66 return ipmid_send_cmd_to_host(std::move(cmd)); 67 } 68 69 // Called into by Command Manager 70 void Host::commandStatusHandler(IpmiCmdData cmd, bool status) 71 { 72 // Need to convert <cmd> to the equivalent one mentioned in spec 73 auto value = status ? Result::Success : Result::Failure; 74 75 // Fire a signal 76 this->commandComplete(intfCommand.at(std::get<0>(cmd)), value); 77 } 78 79 } // namespace command 80 } // namespace host 81 } // namepsace phosphor 82