1 #pragma once
2 
3 #include <tuple>
4 #include <queue>
5 #include <sdbusplus/bus.hpp>
6 #include <sdbusplus/bus/match.hpp>
7 #include <timer.hpp>
8 #include <host-ipmid/ipmid-host-cmd-utils.hpp>
9 
10 namespace phosphor
11 {
12 namespace host
13 {
14 namespace command
15 {
16 
17 /** @class
18  *  @brief Manages commands that are to be sent to Host
19  */
20 class Manager
21 {
22     public:
23         Manager() = delete;
24         ~Manager() = default;
25         Manager(const Manager&) = delete;
26         Manager& operator=(const Manager&) = delete;
27         Manager(Manager&&) = delete;
28         Manager& operator=(Manager&&) = delete;
29 
30         /** @brief Constructs Manager object
31          *
32          *  @param[in] bus   - dbus handler
33          *  @param[in] event - pointer to sd_event
34          */
35         Manager(sdbusplus::bus::bus& bus, sd_event* event);
36 
37         /** @brief  Extracts the next entry in the queue and returns
38          *          Command and data part of it.
39          *
40          *  @detail Also calls into the registered handlers so that they can now
41          *          send the CommandComplete signal since the interface contract
42          *          is that we emit this signal once the message has been
43          *          passed to the host (which is required when calling this)
44          *
45          *          Also, if the queue has more commands, then it will alert the
46          *          host
47          */
48         IpmiCmdData getNextCommand();
49 
50         /** @brief  Pushes the command onto the queue.
51          *
52          *  @detail If the queue is empty, then it alerts the Host. If not,
53          *          then it returns and the API documented above will handle
54          *          the commands in Queue.
55          *
56          *  @param[in] command - tuple of <IPMI command, data, callback>
57          */
58         void execute(CommandHandler command);
59 
60     private:
61         /** @brief Check if anything in queue and alert host if so */
62         void checkQueueAndAlertHost();
63 
64         /** @brief  Call back interface on message timeouts to host.
65          *
66          *  @detail When this happens, a failure message would be sent
67          *          to all the commands that are in the Queue and queue
68          *          will be purged
69          */
70         void hostTimeout();
71 
72         /** @brief Clears the command queue
73          *
74          *  @detail Clears the command queue and calls all callbacks
75          *          specifying the command wasn't successful.
76          */
77         void clearQueue();
78 
79         /** @brief Clears the command queue on a power on
80          *
81          *  @detail The properties changed handler for the
82          *          RequestedHostTransition property.  When this property
83          *          changes to 'On', this function will purge the command
84          *          queue.
85          *
86          *          This is done to avoid having commands that were issued
87          *          before the host powers on from getting sent to the host,
88          *          either due to race conditions around state transitions
89          *          or from a user doing something like requesting an already
90          *          powered off system to power off again and then immediately
91          *          requesting a power on.
92          *
93          *  @param[in] msg - the sdbusplus message containing the property
94          */
95         void clearQueueOnPowerOn(sdbusplus::message::message& msg);
96 
97         /** @brief Reference to the dbus handler */
98         sdbusplus::bus::bus& bus;
99 
100         /** @brief Queue to store the requested commands */
101         std::queue<CommandHandler> workQueue{};
102 
103         /** @brief Timer for commands to host */
104         phosphor::ipmi::Timer timer;
105 
106         /** @brief Match handler for the requested host state */
107         sdbusplus::bus::match_t hostTransitionMatch;
108 };
109 
110 } // namespace command
111 } // namespace host
112 } // namespace phosphor
113