blob: be2bd99b9c204a4bc305c8e298917e5b7a90133f [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"
Andrew Geissler83159702017-04-03 13:31:13 -05006#include "elog-errors.hpp"
Andrew Geisslerdd2c6fd2017-03-16 15:53:20 -05007
8namespace phosphor
9{
10namespace host
11{
12
Andrew Geissler1b9d4e52017-03-21 15:04:05 -050013constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
14constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
15constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
16
Andrew Geissler1c1bd752017-03-20 21:17:04 -050017using namespace phosphor::logging;
18
19// When you see base:: you know we're referencing our base class
20namespace base = sdbusplus::xyz::openbmc_project::Control::server;
21
Andrew Geissler83159702017-04-03 13:31:13 -050022base::Host::Command Host::getNextCommand()
23{
24 // Stop the timer
25 auto r = timer.setTimer(SD_EVENT_OFF);
26 if (r < 0)
27 {
28 log<level::ERR>("Failure to STOP the timer",
29 entry("ERROR=%s", strerror(-r)));
30 }
31
32 if(this->workQueue.empty())
33 {
34 log<level::ERR>("Control Host work queue is empty!");
35 elog<xyz::openbmc_project::Control::Internal::Host::QueueEmpty>();
36 }
37
38 // Pop the processed entry off the queue
39 Command command = this->workQueue.front();
40 this->workQueue.pop();
41
42 // Issue command complete signal
43 this->commandComplete(command, Result::Success);
44
45 // Check for another entry in the queue and kick it off
46 this->checkQueue();
47 return command;
48}
49
50void Host::hostTimeout()
51{
52 log<level::ERR>("Host control timeout hit!");
53 // Dequeue all entries and send fail signal
54 while(!this->workQueue.empty())
55 {
56 auto command = this->workQueue.front();
57 this->workQueue.pop();
58 this->commandComplete(command,Result::Failure);
59 }
60}
Andrew Geissler1b9d4e52017-03-21 15:04:05 -050061
Andrew Geissler0c07c322017-03-22 14:02:30 -050062void Host::checkQueue()
63{
64 if (this->workQueue.size() >= 1)
Andrew Geissler1b9d4e52017-03-21 15:04:05 -050065 {
66 log<level::INFO>("Asserting SMS Attention");
67
68 std::string IPMI_PATH("/org/openbmc/HostIpmi/1");
69 std::string IPMI_INTERFACE("org.openbmc.HostIpmi");
70
Andrew Geissler83159702017-04-03 13:31:13 -050071 auto host = ::ipmi::getService(this->bus,IPMI_INTERFACE,IPMI_PATH);
72
73 // Start the timer for this transaction
74 auto time = std::chrono::duration_cast<std::chrono::microseconds>(
75 std::chrono::seconds(IPMI_SMS_ATN_ACK_TIMEOUT_SECS));
76 auto r = timer.startTimer(time);
77 if (r < 0)
78 {
79 log<level::ERR>("Error starting timer for control host");
80 return;
81 }
Andrew Geissler1b9d4e52017-03-21 15:04:05 -050082
83 auto method = this->bus.new_method_call(host.c_str(),
84 IPMI_PATH.c_str(),
85 IPMI_INTERFACE.c_str(),
86 "setAttention");
87 auto reply = this->bus.call(method);
88
89 if (reply.is_method_error())
90 {
91 log<level::ERR>("Error in setting SMS attention");
92 throw std::runtime_error("ERROR in call to setAttention");
93 }
94 log<level::INFO>("SMS Attention asserted");
95 }
Andrew Geissler0c07c322017-03-22 14:02:30 -050096}
97
98void Host::execute(base::Host::Command command)
99{
100 log<level::INFO>("Pushing cmd on to queue",
101 entry("CONTROL_HOST_CMD=%s",
102 convertForMessage(command)));
103
104 this->workQueue.push(command);
105
106 // Alert host if this is only command in queue otherwise host will
107 // be notified of next message after processing the current one
108 if (this->workQueue.size() == 1)
109 {
110 this->checkQueue();
111 }
112 else
113 {
114 log<level::INFO>("Command in process, no attention");
115 }
Andrew Geissler1b9d4e52017-03-21 15:04:05 -0500116
Andrew Geissler62817fa92017-03-20 14:20:49 -0500117 return;
118}
119
Andrew Geisslerdd2c6fd2017-03-16 15:53:20 -0500120} // namespace host
121} // namepsace phosphor