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