1 #pragma once 2 3 #include "sol/sol_manager.hpp" 4 5 #include <systemd/sd-event.h> 6 7 #include <boost/asio/io_context.hpp> 8 #include <chrono> 9 #include <map> 10 11 namespace eventloop 12 { 13 14 /** @struct EventSourceDeleter 15 * 16 * Custom deleter for the sd_event_source*. 17 */ 18 struct EventSourceDeleter 19 { 20 void operator()(sd_event_source* event) const 21 { 22 event = sd_event_source_unref(event); 23 } 24 }; 25 26 using EventSource = std::unique_ptr<sd_event_source, EventSourceDeleter>; 27 using 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 */ 37 enum class Timers 38 { 39 ACCUMULATE, /**< Character Accumulate Timer */ 40 RETRY, /**< Retry Interval Timer */ 41 }; 42 43 class EventLoop 44 { 45 public: 46 explicit EventLoop(std::shared_ptr<boost::asio::io_context> io) : io(io) 47 { 48 } 49 EventLoop() = delete; 50 ~EventLoop() = default; 51 EventLoop(const EventLoop&) = delete; 52 EventLoop& operator=(const EventLoop&) = delete; 53 EventLoop(EventLoop&&) = delete; 54 EventLoop& operator=(EventLoop&&) = delete; 55 56 /** @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>>; 64 65 /** @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>; 71 72 /** @brief Initialise the event loop and add the handler for incoming 73 * IPMI packets. 74 * 75 * @return EXIT_SUCCESS on success and EXIT_FAILURE on failure. 76 */ 77 int startEventLoop(); 78 79 /** @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); 84 85 /** @brief Remove host console I/O event source. */ 86 void stopHostConsole(); 87 88 /** @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); 101 102 /** @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); 111 112 /** @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); 124 125 /** @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); 137 138 /** @brief Event loop object. */ 139 sd_event* event = nullptr; 140 141 private: 142 /** @brief Event source object for host console. */ 143 EventSource hostConsole = nullptr; 144 145 /** @brief boost::asio io context to run with 146 */ 147 std::shared_ptr<boost::asio::io_context> io; 148 149 /** @brief Event source for the UDP socket listening on IPMI standard 150 * port. 151 */ 152 EventSource udpIPMI = nullptr; 153 154 /** @brief Map to keep information regarding IPMI payload instance and 155 * timers for character accumulate interval and retry interval. 156 */ 157 PayloadMap payloadInfo; 158 }; 159 160 } // namespace eventloop 161