blob: 81ad19bbdf7942eb74633e12191b32e37aea38b9 [file] [log] [blame]
Tom Joseph86d17b42017-02-15 14:45:01 +05301#pragma once
2
3#include "console_buffer.hpp"
4#include "session.hpp"
5
6namespace sol
7{
8
9namespace internal
10{
11
12/** @struct SequenceNumbers
13 *
14 * SOL sequence numbers. At the session level, SOL Payloads share the session
15 * sequence numbers for authenticated and unauthenticated packets with other
16 * packets under the IPMI session. At the payload level, SOL packets include
17 * their own message sequence numbers that are used for tracking missing and
18 * retried SOL messages. The sequence numbers must be non-zero. Retried
19 * packets use the same sequence number as the first packet.
20 */
21struct SequenceNumbers
22{
23 static constexpr uint8_t MAX_SOL_SEQUENCE_NUMBER = 0x10;
24
25 /** @brief Get the SOL sequence number.
26 *
27 * @param[in] inbound - true for inbound sequence number and false for
28 * outbound sequence number
29 *
30 * @return sequence number
31 */
32 auto get(bool inbound = true) const
33 {
34 return inbound ? in : out;
35 }
36
37 /** @brief Increment the inbound SOL sequence number. */
38 void incInboundSeqNum()
39 {
40 if ((++in) == MAX_SOL_SEQUENCE_NUMBER)
41 {
42 in = 1;
43 }
44 }
45
46 /** @brief Increment the outbound SOL sequence number.
47 *
48 * @return outbound sequence number to populate the SOL payload.
49 */
50 auto incOutboundSeqNum()
51 {
52 if ((++out) == MAX_SOL_SEQUENCE_NUMBER)
53 {
54 out = 1;
55 }
56
57 return out;
58 }
59
60 private:
61 uint8_t in = 1; //!< Inbound sequence number.
62 uint8_t out = 0; //!< Outbound sequence number, since the first
63 //!< operation is increment, it is initialised to 0
64};
65
66} // namespace internal
67
68/** @class Context
69 *
70 * Context keeps the state of the SOL session. The information needed to
71 * maintain the state of the SOL is part of this class. This class provides
72 * interfaces to handle incoming SOL payload, send response and send outbound
73 * SOL payload.
74 */
75class Context
76{
77 public:
78 Context() = default;
79 ~Context() = default;
80 Context(const Context&) = delete;
81 Context& operator=(const Context&) = delete;
82 Context(Context&&) = default;
83 Context& operator=(Context&&) = default;
84
85 /** @brief Context Constructor.
86 *
87 * This is issued by the SOL Manager when a SOL payload instance is
88 * started for the activate payload command.
89 *
90 * @param[in] maxRetryCount - Retry count max value.
91 * @param[in] sendThreshold - Character send threshold.
92 * @param[in] instance - SOL payload instance.
93 * @param[in] sessionID - BMC session ID.
94 */
95 Context(uint8_t maxRetryCount,
96 uint8_t sendThreshold,
97 uint8_t instance,
98 session::SessionID sessionID):
99 maxRetryCount(maxRetryCount),
100 retryCounter(maxRetryCount),
101 sendThreshold(sendThreshold),
102 payloadInstance(instance),
103 sessionID(sessionID) {}
104
105 static constexpr auto clear = true;
106 static constexpr auto noClear = false;
107
108 /** @brief Retry count max value. */
109 const uint8_t maxRetryCount = 0;
110
111 /** @brief Retry counter. */
112 uint8_t retryCounter = 0;
113
114 /** @brief Character send threshold. */
115 const uint8_t sendThreshold = 0;
116
117 /** @brief SOL payload instance. */
118 const uint8_t payloadInstance = 0;
119
120 /** @brief Session ID. */
121 const session::SessionID sessionID = 0;
122
123 /** @brief Process the Inbound SOL payload.
124 *
125 * The SOL payload from the remote console is processed and the
126 * acknowledgment handling is done.
127 *
128 * @param[in] seqNum - Packet sequence number.
129 * @param[in] ackSeqNum - Packet ACK/NACK sequence number.
130 * @param[in] count - Accepted character count.
131 * @param[in] operation - ACK is false, NACK is true
132 * @param[in] input - Incoming SOL character data.
133 */
134 void processInboundPayload(uint8_t seqNum,
135 uint8_t ackSeqNum,
136 uint8_t count,
137 bool status,
138 const Buffer& input);
139
140 /** @brief Send the outbound SOL payload.
141 *
142 * @return zero on success and negative value if condition for sending
143 * the payload fails.
144 */
145 int sendOutboundPayload();
146
147 /** @brief Resend the SOL payload.
148 *
149 * @param[in] clear - if true then send the payload and clear the
150 * cached payload, if false only send the payload.
151 */
152 void resendPayload(bool clear);
153
154 private:
155 /** @brief Expected character count.
156 *
157 * Expected Sequence number and expected character count is set before
158 * sending the SOL payload. The check is done against these values when
159 * an incoming SOL payload is received.
160 */
161 size_t expectedCharCount = 0;
162
163 /** @brief Inbound and Outbound sequence numbers. */
164 internal::SequenceNumbers seqNums;
165
166 /** @brief Copy of the last sent SOL payload.
167 *
168 * A copy of the SOL payload is kept here, so that when a retry needs
169 * to be attempted the payload is sent again.
170 */
171 Buffer payloadCache;
172
173 /**
174 * @brief Send Response for Incoming SOL payload.
175 *
176 * @param[in] ackSeqNum - Packet ACK/NACK Sequence Number.
177 * @param[in] count - Accepted Character Count.
178 * @param[in] ack - Set ACK/NACK in the Operation.
179 */
180 void prepareResponse(uint8_t ackSeqNum, uint8_t count, bool ack);
181
182 /** @brief Send the outgoing SOL payload.
183 *
184 * @param[in] out - buffer containing the SOL payload.
185 */
186 void sendPayload(const Buffer& out) const;
187};
188
189} // namespace sol