blob: a7e4a1c0f70ecc804bf06456d2a094248bde92ac [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
36 ~CustomFD()
37 {
38 if(fd >=0)
39 {
40 close(fd);
41 }
42 }
43
44 int operator()() const
45 {
46 return fd;
47 }
48
49 private:
50 int fd = -1;
51};
52
53
54/** @class Manager
55 *
56 * Manager class acts a manager for the SOL payload instances and provides
57 * interfaces to start a payload instance, stop a payload instance and get
58 * reference to the context object.
59 */
60class Manager
61{
62 public:
63
64 /** @brief SOL Payload Instance is the key for the map, the value is the
65 * SOL context.
66 */
67 using SOLPayloadMap = std::map<Instance, std::unique_ptr<Context>>;
68
69 Manager() = default;
70 ~Manager() = default;
71 Manager(const Manager&) = delete;
72 Manager& operator=(const Manager&) = delete;
73 Manager(Manager&&) = default;
74 Manager& operator=(Manager&&) = default;
75
76 /** @brief Host Console Buffer. */
77 ConsoleData dataBuffer;
78
79
80 /** @brief Character Accumulate Interval
81 *
82 * Character Accumulate Interval in 5 ms increments, 1-based. This sets
83 * the typical amount of time that the BMC will wait before
84 * transmitting a partial SOL character data packet. (Where a partial
85 * packet is defined as a packet that has fewer characters to transmit
86 * than the number of characters specified by the character send
87 * threshold. This parameter can be modified by the set SOL
88 * configuration parameters command.
89 */
90 uint8_t accumulateInterval = 20;
91
92 /** @brief Character Send Threshold
93 *
94 * The BMC will automatically send an SOL character data packet
95 * containing this number of characters as soon as this number of
96 * characters (or greater) has been accepted from the baseboard serial
97 * controller into the BMC. This provides a mechanism to tune the
98 * buffer to reduce latency to when the first characters are received
99 * after an idle interval. In the degenerate case, setting this value
100 * to a ‘1’ would cause the BMC to send a packet as soon as the first
101 * character was received. This parameter can be modified by the set
102 * SOL configuration parameters command.
103 */
104 uint8_t sendThreshold = 1;
105
106 /** @brief Retry Count
107 *
108 * 1-based. 0 = no retries after packet is transmitted. Packet will be
109 * dropped if no ACK/NACK received by time retries expire. The maximum
110 * value for retry count is 7. This parameter can be modified by the
111 * set SOL configuration parameters command.
112 */
113 uint8_t retryCount = 7;
114
115 /** @brief Retry Interval
116 *
117 * Retry Interval, 1-based. Retry Interval in 10 ms increments. Sets
118 * the time that the BMC will wait before the first retry and the time
119 * between retries when sending SOL packets to the remote console. 00h
120 * indicates retries sent back-to-back. This parameter can be modified
121 * by the set SOL configuration parameters command.
122 */
123 uint8_t retryThreshold = 10;
124
125 /** @brief Start a SOL payload instance.
126 *
127 * Starting a payload instance involves creating the context object,
128 * add the accumulate interval timer and retry interval timer to the
129 * event loop.
130 *
131 * @param[in] payloadInstance - SOL payload instance.
132 * @param[in] sessionID - BMC session ID.
133 */
134 void startPayloadInstance(uint8_t payloadInstance,
135 session::SessionID sessionID);
136
137 /** @brief Stop SOL payload instance.
138 *
139 * Stopping a payload instance involves stopping and removing the
140 * accumulate interval timer and retry interval timer from the event
141 * loop, delete the context object.
142 *
143 * @param[in] payloadInstance - SOL payload instance
144 */
145 void stopPayloadInstance(uint8_t payloadInstance);
146
147 /** @brief Get SOL Context by Payload Instance.
148 *
149 * @param[in] payloadInstance - SOL payload instance.
150 *
151 * @return reference to the SOL payload context.
152 */
153 Context& getContext(uint8_t payloadInstance)
154 {
155 auto iter = payloadMap.find(payloadInstance);
156
157 if (iter != payloadMap.end())
158 {
159 return *(iter->second);
160 }
161
162 std::string msg = "Invalid SOL payload instance " + payloadInstance;
163 throw std::runtime_error(msg.c_str());
164 }
165
166 /** @brief Get SOL Context by Session ID.
167 *
168 * @param[in] sessionID - IPMI Session ID.
169 *
170 * @return reference to the SOL payload context.
171 */
172 Context& getContext(session::SessionID sessionID)
173 {
174 for (const auto& kv : payloadMap)
175 {
176 if (kv.second->sessionID == sessionID)
177 {
178 return *kv.second;
179 }
180 }
181
182 std::string msg = "Invalid SOL SessionID " + sessionID;
183 throw std::runtime_error(msg.c_str());
184 }
185
186 /** @brief Check if SOL payload is active.
187 *
188 * @param[in] payloadInstance - SOL payload instance.
189 *
190 * @return true if the instance is active and false it is not active.
191 */
192 auto isPayloadActive(uint8_t payloadInstance) const
193 {
194 return (0 != payloadMap.count(payloadInstance));
195 }
196
197 /** @brief Write data to the host console unix socket.
198 *
199 * @param[in] input - Data from the remote console.
200 *
201 * @return 0 on success and errno on failure.
202 */
203 int writeConsoleSocket(const Buffer& input) const;
204
205 private:
206 SOLPayloadMap payloadMap;
207
208 /** @brief File descriptor for the host console. */
209 std::unique_ptr<CustomFD> consoleFD = nullptr;
210
211 /** @brief Initialize the host console file descriptor. */
212 void initHostConsoleFd();
213};
214
215} //namespace sol