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