| Tom Joseph | 807c7e8 | 2017-02-09 19:49:38 +0530 | [diff] [blame] | 1 | #pragma once | 
|  | 2 |  | 
| Vernon Mauery | 9e801a2 | 2018-10-12 13:20:49 -0700 | [diff] [blame] | 3 | #include "sol/sol_manager.hpp" | 
|  | 4 |  | 
| Tom Joseph | 807c7e8 | 2017-02-09 19:49:38 +0530 | [diff] [blame] | 5 | #include <systemd/sd-event.h> | 
| Vernon Mauery | 9e801a2 | 2018-10-12 13:20:49 -0700 | [diff] [blame] | 6 |  | 
| Vernon Mauery | cbccb05 | 2018-10-24 13:52:22 -0700 | [diff] [blame^] | 7 | #include <boost/asio/io_context.hpp> | 
| Tom Joseph | 807c7e8 | 2017-02-09 19:49:38 +0530 | [diff] [blame] | 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 | { | 
| Vernon Mauery | 9e801a2 | 2018-10-12 13:20:49 -0700 | [diff] [blame] | 39 | ACCUMULATE, /**< Character Accumulate Timer */ | 
|  | 40 | RETRY,      /**< Retry Interval Timer */ | 
| Tom Joseph | 807c7e8 | 2017-02-09 19:49:38 +0530 | [diff] [blame] | 41 | }; | 
|  | 42 |  | 
|  | 43 | class EventLoop | 
|  | 44 | { | 
| Vernon Mauery | 9e801a2 | 2018-10-12 13:20:49 -0700 | [diff] [blame] | 45 | public: | 
| Vernon Mauery | cbccb05 | 2018-10-24 13:52:22 -0700 | [diff] [blame^] | 46 | explicit EventLoop(std::shared_ptr<boost::asio::io_context> io) : io(io) | 
|  | 47 | { | 
|  | 48 | } | 
|  | 49 | EventLoop() = delete; | 
| Vernon Mauery | 9e801a2 | 2018-10-12 13:20:49 -0700 | [diff] [blame] | 50 | ~EventLoop() = default; | 
|  | 51 | EventLoop(const EventLoop&) = delete; | 
|  | 52 | EventLoop& operator=(const EventLoop&) = delete; | 
|  | 53 | EventLoop(EventLoop&&) = delete; | 
|  | 54 | EventLoop& operator=(EventLoop&&) = delete; | 
| Tom Joseph | 807c7e8 | 2017-02-09 19:49:38 +0530 | [diff] [blame] | 55 |  | 
| Vernon Mauery | 9e801a2 | 2018-10-12 13:20:49 -0700 | [diff] [blame] | 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>>; | 
| Tom Joseph | 807c7e8 | 2017-02-09 19:49:38 +0530 | [diff] [blame] | 64 |  | 
| Vernon Mauery | 9e801a2 | 2018-10-12 13:20:49 -0700 | [diff] [blame] | 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>; | 
| Tom Joseph | 807c7e8 | 2017-02-09 19:49:38 +0530 | [diff] [blame] | 71 |  | 
| Vernon Mauery | 9e801a2 | 2018-10-12 13:20:49 -0700 | [diff] [blame] | 72 | /** @brief Initialise the event loop and add the handler for incoming | 
|  | 73 | *         IPMI packets. | 
| Vernon Mauery | 9e801a2 | 2018-10-12 13:20:49 -0700 | [diff] [blame] | 74 | * | 
|  | 75 | *  @return EXIT_SUCCESS on success and EXIT_FAILURE on failure. | 
|  | 76 | */ | 
| Vernon Mauery | cbccb05 | 2018-10-24 13:52:22 -0700 | [diff] [blame^] | 77 | int startEventLoop(); | 
| Tom Joseph | 807c7e8 | 2017-02-09 19:49:38 +0530 | [diff] [blame] | 78 |  | 
| Vernon Mauery | 9e801a2 | 2018-10-12 13:20:49 -0700 | [diff] [blame] | 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); | 
| Tom Joseph | 807c7e8 | 2017-02-09 19:49:38 +0530 | [diff] [blame] | 84 |  | 
| Vernon Mauery | 9e801a2 | 2018-10-12 13:20:49 -0700 | [diff] [blame] | 85 | /** @brief Remove host console I/O event source. */ | 
|  | 86 | void stopHostConsole(); | 
| Tom Joseph | 28d993a | 2017-04-21 20:47:53 +0530 | [diff] [blame] | 87 |  | 
| Vernon Mauery | 9e801a2 | 2018-10-12 13:20:49 -0700 | [diff] [blame] | 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); | 
| Tom Joseph | 807c7e8 | 2017-02-09 19:49:38 +0530 | [diff] [blame] | 101 |  | 
| Vernon Mauery | 9e801a2 | 2018-10-12 13:20:49 -0700 | [diff] [blame] | 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); | 
| Tom Joseph | 807c7e8 | 2017-02-09 19:49:38 +0530 | [diff] [blame] | 111 |  | 
| Vernon Mauery | 9e801a2 | 2018-10-12 13:20:49 -0700 | [diff] [blame] | 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); | 
| Tom Joseph | 807c7e8 | 2017-02-09 19:49:38 +0530 | [diff] [blame] | 124 |  | 
| Vernon Mauery | 9e801a2 | 2018-10-12 13:20:49 -0700 | [diff] [blame] | 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); | 
| Tom Joseph | 807c7e8 | 2017-02-09 19:49:38 +0530 | [diff] [blame] | 137 |  | 
| Vernon Mauery | 9e801a2 | 2018-10-12 13:20:49 -0700 | [diff] [blame] | 138 | /** @brief Event loop object. */ | 
|  | 139 | sd_event* event = nullptr; | 
| Tom Joseph | 807c7e8 | 2017-02-09 19:49:38 +0530 | [diff] [blame] | 140 |  | 
| Vernon Mauery | 9e801a2 | 2018-10-12 13:20:49 -0700 | [diff] [blame] | 141 | private: | 
|  | 142 | /** @brief Event source object for host console. */ | 
|  | 143 | EventSource hostConsole = nullptr; | 
| Ratan Gupta | 04edb9b | 2018-03-20 23:06:06 +0530 | [diff] [blame] | 144 |  | 
| Vernon Mauery | cbccb05 | 2018-10-24 13:52:22 -0700 | [diff] [blame^] | 145 | /** @brief boost::asio io context to run with | 
|  | 146 | */ | 
|  | 147 | std::shared_ptr<boost::asio::io_context> io; | 
|  | 148 |  | 
| Vernon Mauery | 9e801a2 | 2018-10-12 13:20:49 -0700 | [diff] [blame] | 149 | /** @brief Event source for the UDP socket listening on IPMI standard | 
|  | 150 | *         port. | 
|  | 151 | */ | 
|  | 152 | EventSource udpIPMI = nullptr; | 
| Tom Joseph | 807c7e8 | 2017-02-09 19:49:38 +0530 | [diff] [blame] | 153 |  | 
| Vernon Mauery | 9e801a2 | 2018-10-12 13:20:49 -0700 | [diff] [blame] | 154 | /** @brief Map to keep information regarding IPMI payload instance and | 
|  | 155 | *         timers for character accumulate interval and retry interval. | 
|  | 156 | */ | 
|  | 157 | PayloadMap payloadInfo; | 
| Tom Joseph | 807c7e8 | 2017-02-09 19:49:38 +0530 | [diff] [blame] | 158 | }; | 
|  | 159 |  | 
|  | 160 | } // namespace eventloop |