1 #pragma once
2 
3 #include <ipmid-host/cmd-utils.hpp>
4 #include <queue>
5 #include <sdbusplus/bus.hpp>
6 #include <sdbusplus/bus/match.hpp>
7 #include <sdbusplus/timer.hpp>
8 #include <tuple>
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     explicit Manager(sdbusplus::bus_t& bus);
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_t& msg);
96 
97     /** @brief Reference to the dbus handler */
98     sdbusplus::bus_t& 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::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