blob: 0d9c2681644c37bf4b2c111554abb46807d5f7d0 [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 Initialize the timers for the SOL payload instance
80 *
81 * This API would add the Character accumulate interval timer event
82 * source and the retry interval timer event source for the SOL payload
83 * instance to the event loop.
84 *
85 * @param[in] payloadInst - SOL payload instance.
86 * @param[in] accumulateInterval - Character accumulate interval.
87 * @param[in] retryInterval - Retry interval.
88 */
89 void startSOLPayloadInstance(uint8_t payloadInst,
90 IntervalType accumulateInterval,
91 IntervalType retryInterval);
Tom Joseph807c7e82017-02-09 19:49:38 +053092
Vernon Mauery9e801a22018-10-12 13:20:49 -070093 /** @brief Stop the timers for the SOL payload instance.
94 *
95 * This would remove the character accumulate interval timer event
96 * source and the retry interval timer event source from the event
97 * loop.
98 *
99 * @param[in] payloadInst - SOL payload instance
100 */
101 void stopSOLPayloadInstance(uint8_t payloadInst);
Tom Joseph807c7e82017-02-09 19:49:38 +0530102
Vernon Mauery9e801a22018-10-12 13:20:49 -0700103 /** @brief Modify the timer event source to enable/disable.
104 *
105 * When the timer is enabled, the timer it set to fire again at
106 * timer's interval for the instance added to the event loop iteration
107 * timestamp. When the timer is disabled, the event source for the
108 * timer is disabled.
109 *
110 * @param[in] payloadInst - SOL payload instance.
111 * @param[in] type - Timer type.
112 * @param[in] status - on/off the event source.
113 */
114 void switchTimer(uint8_t payloadInst, Timers type, bool status);
Tom Joseph807c7e82017-02-09 19:49:38 +0530115
Vernon Mauery9e801a22018-10-12 13:20:49 -0700116 /** @brief Modify the retry interval timer event source to enable/
117 * disable
118 *
119 * When the timer is enabled, the timer it set to fire again at
120 * retry interval for the instance added to the event loop iteration
121 * timestamp. When the timer is disabled the event source for the
122 * retry interval timer is disabled.
123 *
124 * @param[in] payloadInst - SOL payload instance.
125 * @param[in] status - on/off the event source.
126 */
127 void switchRetryTimer(uint8_t payloadInst, bool status);
Tom Joseph807c7e82017-02-09 19:49:38 +0530128
Vernon Mauery9e801a22018-10-12 13:20:49 -0700129 /** @brief Event loop object. */
130 sd_event* event = nullptr;
Tom Joseph807c7e82017-02-09 19:49:38 +0530131
Vernon Mauery9e801a22018-10-12 13:20:49 -0700132 private:
Vernon Mauery7a0142c2018-11-09 08:38:16 -0800133 /** @brief async handler for incoming udp packets */
134 void handleRmcpPacket();
135
136 /** @brief register the async handler for incoming udp packets */
137 void startRmcpReceive();
138
Vernon Mauerycbccb052018-10-24 13:52:22 -0700139 /** @brief boost::asio io context to run with
140 */
141 std::shared_ptr<boost::asio::io_context> io;
142
Vernon Mauery7a0142c2018-11-09 08:38:16 -0800143 /** @brief boost::asio udp socket
Vernon Mauery9e801a22018-10-12 13:20:49 -0700144 */
Vernon Mauery7a0142c2018-11-09 08:38:16 -0800145 std::shared_ptr<boost::asio::ip::udp::socket> udpSocket = nullptr;
Tom Joseph807c7e82017-02-09 19:49:38 +0530146
Vernon Mauery9e801a22018-10-12 13:20:49 -0700147 /** @brief Map to keep information regarding IPMI payload instance and
148 * timers for character accumulate interval and retry interval.
149 */
150 PayloadMap payloadInfo;
Tom Joseph807c7e82017-02-09 19:49:38 +0530151};
152
153} // namespace eventloop