blob: 5218b2735c900fb8cb98285bb4584e56c1a8a11f [file] [log] [blame]
Tom Joseph807c7e82017-02-09 19:49:38 +05301#pragma once
2
Vernon Mauery9e801a22018-10-12 13:20:49 -07003#include "sol/sol_manager.hpp"
4
Tom Joseph807c7e82017-02-09 19:49:38 +05305#include <systemd/sd-event.h>
Vernon Mauery9e801a22018-10-12 13:20:49 -07006
Vernon Mauerycbccb052018-10-24 13:52:22 -07007#include <boost/asio/io_context.hpp>
Tom Joseph807c7e82017-02-09 19:49:38 +05308#include <chrono>
9#include <map>
10
11namespace eventloop
12{
13
14/** @struct EventSourceDeleter
15 *
16 * Custom deleter for the sd_event_source*.
17 */
18struct EventSourceDeleter
19{
20 void operator()(sd_event_source* event) const
21 {
22 event = sd_event_source_unref(event);
23 }
24};
25
26using EventSource = std::unique_ptr<sd_event_source, EventSourceDeleter>;
27using IntervalType = std::chrono::microseconds;
28
29/** @enum Timers
30 *
31 * For SOL functioning, there are two timers involved. The character accumulate
32 * interval timer is the amount of time that the BMC will wait before
33 * transmitting a partial SOL packet. The retry interval timer is the time that
34 * BMC will wait before the first retry and the time between retries when
35 * sending SOL packets to the remote console.
36 */
37enum class Timers
38{
Vernon Mauery9e801a22018-10-12 13:20:49 -070039 ACCUMULATE, /**< Character Accumulate Timer */
40 RETRY, /**< Retry Interval Timer */
Tom Joseph807c7e82017-02-09 19:49:38 +053041};
42
43class EventLoop
44{
Vernon Mauery9e801a22018-10-12 13:20:49 -070045 public:
Vernon Mauerycbccb052018-10-24 13:52:22 -070046 explicit EventLoop(std::shared_ptr<boost::asio::io_context> io) : io(io)
47 {
48 }
49 EventLoop() = delete;
Vernon Mauery9e801a22018-10-12 13:20:49 -070050 ~EventLoop() = default;
51 EventLoop(const EventLoop&) = delete;
52 EventLoop& operator=(const EventLoop&) = delete;
53 EventLoop(EventLoop&&) = delete;
54 EventLoop& operator=(EventLoop&&) = delete;
Tom Joseph807c7e82017-02-09 19:49:38 +053055
Vernon Mauery9e801a22018-10-12 13:20:49 -070056 /** @brief Timer Map
57 *
58 * The key for the timer map is the timer type. There are two types of
59 * timers, character accumulate timer and retry interval timer. The
60 * entries in the values is the event source for the timer and the
61 * interval.
62 */
63 using TimerMap = std::map<Timers, std::tuple<EventSource, IntervalType>>;
Tom Joseph807c7e82017-02-09 19:49:38 +053064
Vernon Mauery9e801a22018-10-12 13:20:49 -070065 /** @brief SOL Payload Map.
66 *
67 * The key for the payload map is the payload instance, the entries in
68 * the value are a map of timers.
69 */
70 using PayloadMap = std::map<uint8_t, TimerMap>;
Tom Joseph807c7e82017-02-09 19:49:38 +053071
Vernon Mauery9e801a22018-10-12 13:20:49 -070072 /** @brief Initialise the event loop and add the handler for incoming
73 * IPMI packets.
Vernon Mauery9e801a22018-10-12 13:20:49 -070074 *
75 * @return EXIT_SUCCESS on success and EXIT_FAILURE on failure.
76 */
Vernon Mauerycbccb052018-10-24 13:52:22 -070077 int startEventLoop();
Tom Joseph807c7e82017-02-09 19:49:38 +053078
Vernon Mauery9e801a22018-10-12 13:20:49 -070079 /** @brief Add host console I/O event source to the event loop.
80 *
81 * @param[in] fd - File descriptor for host console socket.
82 */
83 void startHostConsole(const sol::CustomFD& fd);
Tom Joseph807c7e82017-02-09 19:49:38 +053084
Vernon Mauery9e801a22018-10-12 13:20:49 -070085 /** @brief Remove host console I/O event source. */
86 void stopHostConsole();
Tom Joseph28d993a2017-04-21 20:47:53 +053087
Vernon Mauery9e801a22018-10-12 13:20:49 -070088 /** @brief Initialize the timers for the SOL payload instance
89 *
90 * This API would add the Character accumulate interval timer event
91 * source and the retry interval timer event source for the SOL payload
92 * instance to the event loop.
93 *
94 * @param[in] payloadInst - SOL payload instance.
95 * @param[in] accumulateInterval - Character accumulate interval.
96 * @param[in] retryInterval - Retry interval.
97 */
98 void startSOLPayloadInstance(uint8_t payloadInst,
99 IntervalType accumulateInterval,
100 IntervalType retryInterval);
Tom Joseph807c7e82017-02-09 19:49:38 +0530101
Vernon Mauery9e801a22018-10-12 13:20:49 -0700102 /** @brief Stop the timers for the SOL payload instance.
103 *
104 * This would remove the character accumulate interval timer event
105 * source and the retry interval timer event source from the event
106 * loop.
107 *
108 * @param[in] payloadInst - SOL payload instance
109 */
110 void stopSOLPayloadInstance(uint8_t payloadInst);
Tom Joseph807c7e82017-02-09 19:49:38 +0530111
Vernon Mauery9e801a22018-10-12 13:20:49 -0700112 /** @brief Modify the timer event source to enable/disable.
113 *
114 * When the timer is enabled, the timer it set to fire again at
115 * timer's interval for the instance added to the event loop iteration
116 * timestamp. When the timer is disabled, the event source for the
117 * timer is disabled.
118 *
119 * @param[in] payloadInst - SOL payload instance.
120 * @param[in] type - Timer type.
121 * @param[in] status - on/off the event source.
122 */
123 void switchTimer(uint8_t payloadInst, Timers type, bool status);
Tom Joseph807c7e82017-02-09 19:49:38 +0530124
Vernon Mauery9e801a22018-10-12 13:20:49 -0700125 /** @brief Modify the retry interval timer event source to enable/
126 * disable
127 *
128 * When the timer is enabled, the timer it set to fire again at
129 * retry interval for the instance added to the event loop iteration
130 * timestamp. When the timer is disabled the event source for the
131 * retry interval timer is disabled.
132 *
133 * @param[in] payloadInst - SOL payload instance.
134 * @param[in] status - on/off the event source.
135 */
136 void switchRetryTimer(uint8_t payloadInst, bool status);
Tom Joseph807c7e82017-02-09 19:49:38 +0530137
Vernon Mauery9e801a22018-10-12 13:20:49 -0700138 /** @brief Event loop object. */
139 sd_event* event = nullptr;
Tom Joseph807c7e82017-02-09 19:49:38 +0530140
Vernon Mauery9e801a22018-10-12 13:20:49 -0700141 private:
142 /** @brief Event source object for host console. */
143 EventSource hostConsole = nullptr;
Ratan Gupta04edb9b2018-03-20 23:06:06 +0530144
Vernon Mauerycbccb052018-10-24 13:52:22 -0700145 /** @brief boost::asio io context to run with
146 */
147 std::shared_ptr<boost::asio::io_context> io;
148
Vernon Mauery9e801a22018-10-12 13:20:49 -0700149 /** @brief Event source for the UDP socket listening on IPMI standard
150 * port.
151 */
152 EventSource udpIPMI = nullptr;
Tom Joseph807c7e82017-02-09 19:49:38 +0530153
Vernon Mauery9e801a22018-10-12 13:20:49 -0700154 /** @brief Map to keep information regarding IPMI payload instance and
155 * timers for character accumulate interval and retry interval.
156 */
157 PayloadMap payloadInfo;
Tom Joseph807c7e82017-02-09 19:49:38 +0530158};
159
160} // namespace eventloop