blob: 0bce8882436c5970546a23d488f6005bffb3adba [file] [log] [blame]
Andrew Geissler83159702017-04-03 13:31:13 -05001#include <chrono>
Andrew Geissler1c1bd752017-03-20 21:17:04 -05002#include <phosphor-logging/log.hpp>
Andrew Geissler1b9d4e52017-03-21 15:04:05 -05003#include <utils.hpp>
Andrew Geissler83159702017-04-03 13:31:13 -05004#include <config.h>
Andrew Geisslerdd2c6fd2017-03-16 15:53:20 -05005#include "host-interface.hpp"
6
7namespace phosphor
8{
9namespace host
10{
11
Andrew Geissler1b9d4e52017-03-21 15:04:05 -050012constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
13constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
14constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
15
Andrew Geissler1c1bd752017-03-20 21:17:04 -050016using namespace phosphor::logging;
17
18// When you see base:: you know we're referencing our base class
19namespace base = sdbusplus::xyz::openbmc_project::Control::server;
20
Andrew Geissler83159702017-04-03 13:31:13 -050021base::Host::Command Host::getNextCommand()
22{
23 // Stop the timer
24 auto r = timer.setTimer(SD_EVENT_OFF);
25 if (r < 0)
26 {
27 log<level::ERR>("Failure to STOP the timer",
28 entry("ERROR=%s", strerror(-r)));
29 }
30
31 if(this->workQueue.empty())
32 {
Andrew Geissler758c1ae2017-06-07 21:17:45 -050033 // Just return a heartbeat in this case. A spurious SMS_ATN was
34 // asserted for the host (probably from a previous boot).
35 log<level::INFO>("Control Host work queue is empty!");
36 return (Command::Heartbeat);
Andrew Geissler83159702017-04-03 13:31:13 -050037 }
38
39 // Pop the processed entry off the queue
40 Command command = this->workQueue.front();
41 this->workQueue.pop();
42
43 // Issue command complete signal
44 this->commandComplete(command, Result::Success);
45
46 // Check for another entry in the queue and kick it off
47 this->checkQueue();
48 return command;
49}
50
51void Host::hostTimeout()
52{
53 log<level::ERR>("Host control timeout hit!");
54 // Dequeue all entries and send fail signal
55 while(!this->workQueue.empty())
56 {
57 auto command = this->workQueue.front();
58 this->workQueue.pop();
59 this->commandComplete(command,Result::Failure);
60 }
61}
Andrew Geissler1b9d4e52017-03-21 15:04:05 -050062
Andrew Geissler0c07c322017-03-22 14:02:30 -050063void Host::checkQueue()
64{
65 if (this->workQueue.size() >= 1)
Andrew Geissler1b9d4e52017-03-21 15:04:05 -050066 {
67 log<level::INFO>("Asserting SMS Attention");
68
69 std::string IPMI_PATH("/org/openbmc/HostIpmi/1");
70 std::string IPMI_INTERFACE("org.openbmc.HostIpmi");
71
Andrew Geissler83159702017-04-03 13:31:13 -050072 auto host = ::ipmi::getService(this->bus,IPMI_INTERFACE,IPMI_PATH);
73
74 // Start the timer for this transaction
75 auto time = std::chrono::duration_cast<std::chrono::microseconds>(
76 std::chrono::seconds(IPMI_SMS_ATN_ACK_TIMEOUT_SECS));
77 auto r = timer.startTimer(time);
78 if (r < 0)
79 {
80 log<level::ERR>("Error starting timer for control host");
81 return;
82 }
Andrew Geissler1b9d4e52017-03-21 15:04:05 -050083
84 auto method = this->bus.new_method_call(host.c_str(),
85 IPMI_PATH.c_str(),
86 IPMI_INTERFACE.c_str(),
87 "setAttention");
88 auto reply = this->bus.call(method);
89
90 if (reply.is_method_error())
91 {
92 log<level::ERR>("Error in setting SMS attention");
93 throw std::runtime_error("ERROR in call to setAttention");
94 }
95 log<level::INFO>("SMS Attention asserted");
96 }
Andrew Geissler0c07c322017-03-22 14:02:30 -050097}
98
99void Host::execute(base::Host::Command command)
100{
101 log<level::INFO>("Pushing cmd on to queue",
102 entry("CONTROL_HOST_CMD=%s",
103 convertForMessage(command)));
104
105 this->workQueue.push(command);
106
107 // Alert host if this is only command in queue otherwise host will
108 // be notified of next message after processing the current one
109 if (this->workQueue.size() == 1)
110 {
111 this->checkQueue();
112 }
113 else
114 {
115 log<level::INFO>("Command in process, no attention");
116 }
Andrew Geissler1b9d4e52017-03-21 15:04:05 -0500117
Andrew Geissler62817fa92017-03-20 14:20:49 -0500118 return;
119}
120
Andrew Geisslerdd2c6fd2017-03-16 15:53:20 -0500121} // namespace host
122} // namepsace phosphor