001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      https://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.commons.net.telnet;
019
020/**
021 * The TelnetOptionHandler class is the base class to be used for implementing handlers for Telnet options.
022 * <p>
023 * TelnetOptionHandler implements basic option handling functionality and defines abstract methods that must be implemented to define subnegotiation behavior.
024 * </p>
025 */
026public abstract class TelnetOptionHandler {
027
028    /**
029     * Option code
030     */
031    private int optionCode = -1;
032
033    /**
034     * true if the option should be activated on the local side
035     */
036    private boolean initialLocal;
037
038    /**
039     * true if the option should be activated on the remote side
040     */
041    private boolean initialRemote;
042
043    /**
044     * true if the option should be accepted on the local side
045     */
046    private boolean acceptLocal;
047
048    /**
049     * true if the option should be accepted on the remote side
050     */
051    private boolean acceptRemote;
052
053    /**
054     * true if the option is active on the local side
055     */
056    private boolean doFlag;
057
058    /**
059     * true if the option is active on the remote side
060     */
061    private boolean willFlag;
062
063    /**
064     * Constructor for the TelnetOptionHandler. Allows defining desired initial setting for local/remote activation of this option and behavior in case a
065     * local/remote activation request for this option is received.
066     *
067     * @param optcode        Option code.
068     * @param initlocal      if set to true, a {@code WILL} is sent upon connection.
069     * @param initremote     if set to true, a {@code DO} is sent upon connection.
070     * @param acceptlocal    if set to true, any {@code DO} request is accepted.
071     * @param acceptremote   if set to true, any {@code WILL} request is accepted.
072     */
073    public TelnetOptionHandler(final int optcode, final boolean initlocal, final boolean initremote, final boolean acceptlocal, final boolean acceptremote) {
074        optionCode = optcode;
075        initialLocal = initlocal;
076        initialRemote = initremote;
077        acceptLocal = acceptlocal;
078        acceptRemote = acceptremote;
079    }
080
081    /**
082     * Method called upon reception of a subnegotiation for this option coming from the other end.
083     * <p>
084     * This implementation returns null, and must be overridden by the actual TelnetOptionHandler to specify which response must be sent for the subnegotiation
085     * request.
086     * </p>
087     *
088     * @param suboptionData     the sequence received, without IAC SB &amp; IAC SE
089     * @param suboptionLength   the length of data in suboption_data
090     * @return response to be sent to the subnegotiation sequence. TelnetClient will add IAC SB &amp; IAC SE. null means no response
091     */
092    public int[] answerSubnegotiation(final int suboptionData[], final int suboptionLength) {
093        return null;
094    }
095
096    /**
097     * Gets a boolean indicating whether to accept a DO request coming from the other end.
098     *
099     * @return true if a {@code DO} request shall be accepted.
100     */
101    public boolean getAcceptLocal() {
102        return acceptLocal;
103    }
104
105    /**
106     * Gets a boolean indicating whether to accept a WILL request coming from the other end.
107     *
108     * @return true if a {@code WILL} request shall be accepted.
109     */
110    public boolean getAcceptRemote() {
111        return acceptRemote;
112    }
113
114    /**
115     * Gets a boolean indicating whether a {@code DO} request sent to the other side has been acknowledged.
116     *
117     * @return true if a {@code DO} sent to the other side has been acknowledged.
118     */
119    boolean getDo() {
120        return doFlag;
121    }
122
123    /**
124     * Gets a boolean indicating whether to send a WILL request to the other end upon connection.
125     *
126     * @return true if a {@code WILL} request shall be sent upon connection.
127     */
128    public boolean getInitLocal() {
129        return initialLocal;
130    }
131
132    /**
133     * Gets a boolean indicating whether to send a DO request to the other end upon connection.
134     *
135     * @return true if a {@code DO} request shall be sent upon connection.
136     */
137    public boolean getInitRemote() {
138        return initialRemote;
139    }
140
141    /**
142     * Gets the option code for this option.
143     *
144     * @return Option code.
145     */
146    public int getOptionCode() {
147        return optionCode;
148    }
149
150    /**
151     * Gets a boolean indicating whether a {@code WILL} request sent to the other side has been acknowledged.
152     *
153     * @return true if a {@code WILL} sent to the other side has been acknowledged.
154     */
155    boolean getWill() {
156        return willFlag;
157    }
158
159    /**
160     * Sets behavior of the option for DO requests coming from the other end.
161     *
162     * @param accept   if true, subsequent DO requests will be accepted.
163     */
164    public void setAcceptLocal(final boolean accept) {
165        acceptLocal = accept;
166    }
167
168    /**
169     * Sets behavior of the option for {@code WILL} requests coming from the other end.
170     *
171     * @param accept   if true, subsequent {@code WILL} requests will be accepted.
172     */
173    public void setAcceptRemote(final boolean accept) {
174        acceptRemote = accept;
175    }
176
177    /**
178     * Sets this option whether a {@code DO} request sent to the other side has been acknowledged (invoked by TelnetClient).
179     *
180     * @param state   if true, a {@code DO} request has been acknowledged.
181     */
182    void setDo(final boolean state) {
183        doFlag = state;
184    }
185
186    /**
187     * Sets this option whether to send a {@code WILL} request upon connection.
188     *
189     * @param init   if true, a {@code WILL} request will be sent upon subsequent connections.
190     */
191    public void setInitLocal(final boolean init) {
192        initialLocal = init;
193    }
194
195    /**
196     * Sets this option whether to send a {@code DO} request upon connection.
197     *
198     * @param init   if true, a {@code DO} request will be sent upon subsequent connections.
199     */
200    public void setInitRemote(final boolean init) {
201        initialRemote = init;
202    }
203
204    /**
205     * Sets this option whether a {@code WILL} request sent to the other side has been acknowledged (invoked by TelnetClient).
206     *
207     * @param state   if true, a {@code WILL} request has been acknowledged.
208     */
209    void setWill(final boolean state) {
210        willFlag = state;
211    }
212
213    /**
214     * This method is invoked whenever this option is acknowledged active on the local end (TelnetClient sent a WILL, remote side sent a DO). The method is used
215     * to specify a subnegotiation sequence that will be sent by TelnetClient when the option is activated.
216     * <p>
217     * This implementation returns null, and must be overriden by the actual TelnetOptionHandler to specify which response must be sent for the subnegotiation
218     * request.
219     * </p>
220     *
221     * @return subnegotiation sequence to be sent by TelnetClient. TelnetClient will add IAC SB &amp; IAC SE. null means no subnegotiation.
222     */
223    public int[] startSubnegotiationLocal() {
224        return null;
225    }
226
227    /**
228     * This method is invoked whenever this option is acknowledged active on the remote end (TelnetClient sent a DO, remote side sent a WILL). The method is
229     * used to specify a subnegotiation sequence that will be sent by TelnetClient when the option is activated.
230     * <p>
231     * This implementation returns null, and must be overridden by the actual TelnetOptionHandler to specify which response must be sent for the subnegotiation
232     * request.
233     * </p>
234     *
235     * @return subnegotiation sequence to be sent by TelnetClient. TelnetClient will add IAC SB &amp; IAC SE. null means no subnegotiation.
236     */
237    public int[] startSubnegotiationRemote() {
238        return null;
239    }
240}