blob: e853acfbcda542d86c6c653f9af9115f7f565795 [file] [log] [blame]
Tom Joseph5a454a22017-02-15 14:51:42 +05301#pragma once
2
3#include <map>
4#include <memory>
5#include "console_buffer.hpp"
6#include "session.hpp"
7#include "sol_context.hpp"
8
9namespace sol
10{
11
12constexpr size_t MAX_PAYLOAD_INSTANCES = 16;
13constexpr size_t MAX_PAYLOAD_SIZE = 255;
14constexpr uint8_t MAJOR_VERSION = 0x01;
15constexpr uint8_t MINOR_VERSION = 0x00;
16
17constexpr char CONSOLE_SOCKET_PATH[] = "\0obmc-console";
18constexpr size_t CONSOLE_SOCKET_PATH_LEN = sizeof(CONSOLE_SOCKET_PATH) - 1;
19
20using Instance = uint8_t;
21
22/** @struct CustomFD
23 *
24 * RAII wrapper for file descriptor.
25 */
26struct CustomFD
27{
28 CustomFD(const CustomFD&) = delete;
29 CustomFD& operator=(const CustomFD&) = delete;
30 CustomFD(CustomFD&&) = delete;
31 CustomFD& operator=(CustomFD&&) = delete;
32
33 CustomFD(int fd) :
34 fd(fd) {}
35
Tom Josephb81f7612017-04-25 17:59:02 +053036 ~CustomFD();
Tom Joseph5a454a22017-02-15 14:51:42 +053037
38 int operator()() const
39 {
40 return fd;
41 }
42
43 private:
44 int fd = -1;
45};
46
Tom Joseph704f3422017-04-26 10:13:03 +053047using namespace std::chrono_literals;
Tom Joseph5a454a22017-02-15 14:51:42 +053048
49/** @class Manager
50 *
51 * Manager class acts a manager for the SOL payload instances and provides
52 * interfaces to start a payload instance, stop a payload instance and get
53 * reference to the context object.
54 */
55class Manager
56{
57 public:
58
59 /** @brief SOL Payload Instance is the key for the map, the value is the
60 * SOL context.
61 */
62 using SOLPayloadMap = std::map<Instance, std::unique_ptr<Context>>;
63
64 Manager() = default;
65 ~Manager() = default;
66 Manager(const Manager&) = delete;
67 Manager& operator=(const Manager&) = delete;
68 Manager(Manager&&) = default;
69 Manager& operator=(Manager&&) = default;
70
71 /** @brief Host Console Buffer. */
72 ConsoleData dataBuffer;
73
Tom Joseph5a454a22017-02-15 14:51:42 +053074 /** @brief Character Accumulate Interval
75 *
Tom Joseph704f3422017-04-26 10:13:03 +053076 * This sets the typical amount of time that the BMC will wait before
Tom Joseph5a454a22017-02-15 14:51:42 +053077 * transmitting a partial SOL character data packet. (Where a partial
78 * packet is defined as a packet that has fewer characters to transmit
79 * than the number of characters specified by the character send
80 * threshold. This parameter can be modified by the set SOL
Tom Joseph704f3422017-04-26 10:13:03 +053081 * configuration parameters command. The SOL configuration parameter,
82 * Character Accumulate Interval is 5 ms increments, 1-based value. The
83 * parameter value is accumulateInterval/5. The accumulateInterval
84 * needs to be a multiple of 5.
Tom Joseph5a454a22017-02-15 14:51:42 +053085 */
Tom Joseph704f3422017-04-26 10:13:03 +053086 std::chrono::milliseconds accumulateInterval = 100ms;
Tom Joseph5a454a22017-02-15 14:51:42 +053087
88 /** @brief Character Send Threshold
89 *
90 * The BMC will automatically send an SOL character data packet
91 * containing this number of characters as soon as this number of
92 * characters (or greater) has been accepted from the baseboard serial
93 * controller into the BMC. This provides a mechanism to tune the
94 * buffer to reduce latency to when the first characters are received
95 * after an idle interval. In the degenerate case, setting this value
96 * to a ‘1’ would cause the BMC to send a packet as soon as the first
97 * character was received. This parameter can be modified by the set
98 * SOL configuration parameters command.
99 */
100 uint8_t sendThreshold = 1;
101
102 /** @brief Retry Count
103 *
104 * 1-based. 0 = no retries after packet is transmitted. Packet will be
105 * dropped if no ACK/NACK received by time retries expire. The maximum
106 * value for retry count is 7. This parameter can be modified by the
107 * set SOL configuration parameters command.
108 */
109 uint8_t retryCount = 7;
110
111 /** @brief Retry Interval
112 *
Tom Joseph704f3422017-04-26 10:13:03 +0530113 * Sets the time that the BMC will wait before the first retry and the
114 * time between retries when sending SOL packets to the remote console.
115 * This parameter can be modified by the set SOL configuration
116 * parameters command. The SOL configuration parameter Retry Interval
117 * is 10 ms increments, 1-based value. The parameter value is
118 * retryInterval/10. The retryInterval needs to be a multiple of 10.
Tom Joseph5a454a22017-02-15 14:51:42 +0530119 */
Tom Joseph704f3422017-04-26 10:13:03 +0530120 std::chrono::milliseconds retryInterval = 100ms;
Tom Joseph5a454a22017-02-15 14:51:42 +0530121
122 /** @brief Start a SOL payload instance.
123 *
124 * Starting a payload instance involves creating the context object,
125 * add the accumulate interval timer and retry interval timer to the
126 * event loop.
127 *
128 * @param[in] payloadInstance - SOL payload instance.
129 * @param[in] sessionID - BMC session ID.
130 */
131 void startPayloadInstance(uint8_t payloadInstance,
132 session::SessionID sessionID);
133
134 /** @brief Stop SOL payload instance.
135 *
136 * Stopping a payload instance involves stopping and removing the
137 * accumulate interval timer and retry interval timer from the event
138 * loop, delete the context object.
139 *
140 * @param[in] payloadInstance - SOL payload instance
141 */
142 void stopPayloadInstance(uint8_t payloadInstance);
143
144 /** @brief Get SOL Context by Payload Instance.
145 *
146 * @param[in] payloadInstance - SOL payload instance.
147 *
148 * @return reference to the SOL payload context.
149 */
150 Context& getContext(uint8_t payloadInstance)
151 {
152 auto iter = payloadMap.find(payloadInstance);
153
154 if (iter != payloadMap.end())
155 {
156 return *(iter->second);
157 }
158
159 std::string msg = "Invalid SOL payload instance " + payloadInstance;
160 throw std::runtime_error(msg.c_str());
161 }
162
163 /** @brief Get SOL Context by Session ID.
164 *
165 * @param[in] sessionID - IPMI Session ID.
166 *
167 * @return reference to the SOL payload context.
168 */
169 Context& getContext(session::SessionID sessionID)
170 {
171 for (const auto& kv : payloadMap)
172 {
173 if (kv.second->sessionID == sessionID)
174 {
175 return *kv.second;
176 }
177 }
178
179 std::string msg = "Invalid SOL SessionID " + sessionID;
180 throw std::runtime_error(msg.c_str());
181 }
182
183 /** @brief Check if SOL payload is active.
184 *
185 * @param[in] payloadInstance - SOL payload instance.
186 *
187 * @return true if the instance is active and false it is not active.
188 */
189 auto isPayloadActive(uint8_t payloadInstance) const
190 {
191 return (0 != payloadMap.count(payloadInstance));
192 }
193
194 /** @brief Write data to the host console unix socket.
195 *
196 * @param[in] input - Data from the remote console.
197 *
198 * @return 0 on success and errno on failure.
199 */
200 int writeConsoleSocket(const Buffer& input) const;
201
202 private:
203 SOLPayloadMap payloadMap;
204
205 /** @brief File descriptor for the host console. */
206 std::unique_ptr<CustomFD> consoleFD = nullptr;
207
208 /** @brief Initialize the host console file descriptor. */
209 void initHostConsoleFd();
210};
211
212} //namespace sol