Telnet++ 4.0.0.9
A C++ library for interacting with Telnet streams
Loading...
Searching...
No Matches
option.hpp
1#pragma once
2
3#include "telnetpp/session.hpp"
4
5#include <boost/signals2.hpp>
6
7namespace telnetpp {
8
9//* =========================================================================
39//* =========================================================================
40template <
41 telnetpp::command_type LocalPositive,
42 telnetpp::command_type LocalNegative,
43 telnetpp::command_type RemotePositive,
44 telnetpp::command_type RemoteNegative>
45class option
46{
47public:
48 static constexpr auto local_positive = LocalPositive;
49 static constexpr auto local_negative = LocalNegative;
50 static constexpr auto remote_positive = RemotePositive;
51 static constexpr auto remote_negative = RemoteNegative;
52
53 //* =====================================================================
55 //* =====================================================================
56 virtual ~option() = default;
57
58 //* =====================================================================
60 //* =====================================================================
61 [[nodiscard]] constexpr telnetpp::option_type option_code() const noexcept
62 {
63 return code_;
64 }
65
66 //* =====================================================================
68 //* =====================================================================
69 [[nodiscard]] constexpr bool active() const noexcept
70 {
71 return state_ == internal_state::active;
72 }
73
74 //* =====================================================================
76 //* =====================================================================
77 constexpr void activate()
78 {
79 switch (state_)
80 {
81 case internal_state::inactive:
82 state_ = internal_state::activating;
83 write_negotiation(local_positive);
84 break;
85
86 case internal_state::activating:
87 break;
88
89 case internal_state::active:
90 on_state_changed();
91 break;
92
93 case internal_state::deactivating:
94 break;
95
96 default:
97 assert(!"Unimplemented");
98 break;
99 }
100 }
101
102 //* =====================================================================
104 //* =====================================================================
105 constexpr void deactivate()
106 {
107 switch (state_)
108 {
109 case internal_state::active:
110 state_ = internal_state::deactivating;
111 write_negotiation(local_negative);
112 break;
113
114 case internal_state::activating:
115 break;
116
117 case internal_state::inactive:
118 on_state_changed();
119 break;
120
121 case internal_state::deactivating:
122 break;
123
124 default:
125 assert(!"Unimplemented");
126 break;
127 }
128 }
129
130 //* =====================================================================
134 //* =====================================================================
135 constexpr void negotiate(telnetpp::negotiation_type neg)
136 {
137 switch (state_)
138 {
139 case internal_state::inactive:
140 if (neg == remote_positive)
141 {
142 state_ = internal_state::active;
143 write_negotiation(local_positive);
144 on_state_changed();
145 }
146 else
147 {
148 write_negotiation(local_negative);
149 }
150 break;
151
152 case internal_state::activating:
153 if (neg == remote_positive)
154 {
155 state_ = internal_state::active;
156 on_state_changed();
157 }
158 else
159 {
160 state_ = internal_state::inactive;
161 on_state_changed();
162 }
163 break;
164
165 case internal_state::active:
166 if (neg == remote_positive)
167 {
168 write_negotiation(local_positive);
169 }
170 else
171 {
172 state_ = internal_state::inactive;
173 on_state_changed();
174 write_negotiation(local_negative);
175 }
176 break;
177
178 case internal_state::deactivating:
179 if (neg == remote_positive)
180 {
181 state_ = internal_state::active;
182 on_state_changed();
183 }
184 else
185 {
186 state_ = internal_state::inactive;
187 on_state_changed();
188 }
189 break;
190
191 default:
192 assert(!"Unimplemented");
193 break;
194 }
195 }
196
197 //* =====================================================================
201 //* =====================================================================
202 constexpr void subnegotiate(telnetpp::bytes content)
203 {
204 if (state_ == internal_state::active)
205 {
206 handle_subnegotiation(content);
207 }
208 }
209
210 //* =====================================================================
221 //* =====================================================================
222 boost::signals2::signal<void()> on_state_changed; // NOLINT
223
224protected:
225 //* =====================================================================
227 //* =====================================================================
228 constexpr explicit option(
229 telnetpp::session &sess, telnetpp::option_type code) noexcept
230 : session_{sess}, code_{code}
231 {
232 }
233
234 //* =====================================================================
236 //* =====================================================================
237 void write_text(telnetpp::bytes content)
238 {
239 session_.write(content);
240 }
241
242 //* =====================================================================
244 //* =====================================================================
245 void write_subnegotiation(telnetpp::bytes content)
246 {
247 session_.write(telnetpp::subnegotiation{code_, content});
248 }
249
250private:
251 //* =====================================================================
253 //* =====================================================================
254 void write_negotiation(telnetpp::negotiation_type neg)
255 {
256 session_.write(telnetpp::negotiation{neg, code_});
257 }
258
259 //* =====================================================================
262 //* =====================================================================
263 virtual void handle_subnegotiation(telnetpp::bytes data) = 0;
264
265 enum class internal_state : std::uint8_t
266 {
267 inactive,
268 activating,
269 active,
270 deactivating,
271 };
272
273 telnetpp::session &session_;
274 telnetpp::option_type code_;
275 internal_state state_ = internal_state::inactive;
276};
277
278} // namespace telnetpp
A class that encapsulates a Telnet negotiation.
Definition negotiation.hpp:15
An class that encapsulates one side of a Telnet option.
Definition option.hpp:46
constexpr void subnegotiate(telnetpp::bytes content)
Subnegotiate with the option. This should be called when a subnegotiation sequence has been received ...
Definition option.hpp:202
constexpr void negotiate(telnetpp::negotiation_type neg)
Negotiate with the option. This should be called when the remote side either initiates a negotiation ...
Definition option.hpp:135
virtual ~option()=default
Destructor.
constexpr option(telnetpp::session &sess, telnetpp::option_type code) noexcept
Constructor.
Definition option.hpp:228
constexpr void deactivate()
Begins the deactivation process for the option.
Definition option.hpp:105
void write_text(telnetpp::bytes content)
Write plain text to the session.
Definition option.hpp:237
constexpr void activate()
Begins the activation process for the option.
Definition option.hpp:77
constexpr bool active() const noexcept
Returns whether the option is active.
Definition option.hpp:69
void write_subnegotiation(telnetpp::bytes content)
Write a subnegotiation to the session.
Definition option.hpp:245
constexpr telnetpp::option_type option_code() const noexcept
Returns the code for the option.
Definition option.hpp:61
An abstraction for a Telnet session.
Definition session.hpp:141
void write(telnetpp::element const &elem)
Sends a Telnet data element. Translates the element into a sequence of bytes, that is then sent to th...
Definition session.cpp:96
A class that encapsulates a Telnet subnegotiation.
Definition subnegotiation.hpp:14