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