summaryrefslogtreecommitdiffstats
path: root/host-cmd-manager.hpp
blob: c25706cbc14835933d27e35270b8d87c17fa9d57 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#pragma once

#include <tuple>
#include <queue>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/bus/match.hpp>
#include <timer.hpp>
#include <host-ipmid/ipmid-host-cmd-utils.hpp>

namespace phosphor
{
namespace host
{
namespace command
{

/** @class
 *  @brief Manages commands that are to be sent to Host
 */
class Manager
{
    public:
        Manager() = delete;
        ~Manager() = default;
        Manager(const Manager&) = delete;
        Manager& operator=(const Manager&) = delete;
        Manager(Manager&&) = delete;
        Manager& operator=(Manager&&) = delete;

        /** @brief Constructs Manager object
         *
         *  @param[in] bus   - dbus handler
         *  @param[in] event - pointer to sd_event
         */
        Manager(sdbusplus::bus::bus& bus, sd_event* event);

        /** @brief  Extracts the next entry in the queue and returns
         *          Command and data part of it.
         *
         *  @detail Also calls into the registered handlers so that they can now
         *          send the CommandComplete signal since the interface contract
         *          is that we emit this signal once the message has been
         *          passed to the host (which is required when calling this)
         *
         *          Also, if the queue has more commands, then it will alert the
         *          host
         */
        IpmiCmdData getNextCommand();

        /** @brief  Pushes the command onto the queue.
         *
         *  @detail If the queue is empty, then it alerts the Host. If not,
         *          then it returns and the API documented above will handle
         *          the commands in Queue.
         *
         *  @param[in] command - tuple of <IPMI command, data, callback>
         */
        void execute(CommandHandler command);

    private:
        /** @brief Check if anything in queue and alert host if so */
        void checkQueueAndAlertHost();

        /** @brief  Call back interface on message timeouts to host.
         *
         *  @detail When this happens, a failure message would be sent
         *          to all the commands that are in the Queue and queue
         *          will be purged
         */
        void hostTimeout();

        /** @brief Clears the command queue
         *
         *  @detail Clears the command queue and calls all callbacks
         *          specifying the command wasn't successful.
         */
        void clearQueue();

        /** @brief Clears the command queue on a power on
         *
         *  @detail The properties changed handler for the
         *          RequestedHostTransition property.  When this property
         *          changes to 'On', this function will purge the command
         *          queue.
         *
         *          This is done to avoid having commands that were issued
         *          before the host powers on from getting sent to the host,
         *          either due to race conditions around state transitions
         *          or from a user doing something like requesting an already
         *          powered off system to power off again and then immediately
         *          requesting a power on.
         *
         *  @param[in] msg - the sdbusplus message containing the property
         */
        void clearQueueOnPowerOn(sdbusplus::message::message& msg);

        /** @brief Reference to the dbus handler */
        sdbusplus::bus::bus& bus;

        /** @brief Queue to store the requested commands */
        std::queue<CommandHandler> workQueue{};

        /** @brief Timer for commands to host */
        phosphor::ipmi::Timer timer;

        /** @brief Match handler for the requested host state */
        sdbusplus::bus::match_t hostTransitionMatch;
};

} // namespace command
} // namespace host
} // namespace phosphor
OpenPOWER on IntegriCloud