📄 cwspsession.java
字号:
/**
* JWAP - A Java Implementation of the WAP Protocols
* Copyright (C) 2001-2004 Niko Bender
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package net.sourceforge.jwap.wsp;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Vector;
import net.sourceforge.jwap.util.Logger;
import net.sourceforge.jwap.wsp.pdu.CWSPConnect;
import net.sourceforge.jwap.wsp.pdu.CWSPConnectReply;
import net.sourceforge.jwap.wsp.pdu.CWSPDisconnect;
import net.sourceforge.jwap.wsp.pdu.CWSPGet;
import net.sourceforge.jwap.wsp.pdu.CWSPHeaders;
import net.sourceforge.jwap.wsp.pdu.CWSPPDU;
import net.sourceforge.jwap.wsp.pdu.CWSPPost;
import net.sourceforge.jwap.wsp.pdu.CWSPRedirect;
import net.sourceforge.jwap.wsp.pdu.CWSPReply;
import net.sourceforge.jwap.wsp.pdu.CWSPResume;
import net.sourceforge.jwap.wsp.pdu.CWSPSuspend;
import net.sourceforge.jwap.wsp.pdu.EWSPCorruptPDUException;
import net.sourceforge.jwap.wtp.CWTPEvent;
import net.sourceforge.jwap.wtp.CWTPSocket;
import net.sourceforge.jwap.wtp.EWTPAbortedException;
import net.sourceforge.jwap.wtp.IWTPTransaction;
import net.sourceforge.jwap.wtp.IWTPUpperLayer;
/**
* This class implements the WSP state machine named "management entity"
* in the Wireless Session Protocol Specification by the <a href="http://www.wapforum.org">WAP-forum</a>.
* <br>
* Using this class the programmer can use all methods of the WSP layer.
* To use the WAP-Stack with a class corresponding to HttpURLConnection
* please use WapURLConnection by calling<br>
* <code><br>
* URL example = new URL("wap://wap.nokia.com");<br>
* URLConnection con = example.getConnection();<br>
* </code>
* @author Niko Bender
*/
public class CWSPSession implements IWTPUpperLayer {
// SESSION states
public static final short STATE_NULL = 0;
public static final short STATE_CONNECTING = 1;
public static final short STATE_CONNECTED = 2;
public static final short STATE_SUSPENDED = 3;
public static final short STATE_RESUMING = 4;
// Abort reason code assignments
// Table 35 in spec.
public static final short ABORT_PROTOERR = 0xE0;
public static final short ABORT_DISCONNECT = 0xE1;
public static final short ABORT_SUSPEND = 0xE2;
public static final short ABORT_RESUME = 0xE3;
public static final short ABORT_CONGESTION = 0xE4;
public static final short ABORT_CONNECTERR = 0xE5;
public static final short ABORT_MRUEXCEEDED = 0xE6;
public static final short ABORT_MOREXCEEDED = 0xE7;
public static final short ABORT_PEERREQ = 0xE8;
public static final short ABORT_NETERR = 0xE9;
public static final short ABORT_USERREQ = 0xEA;
public static final short ABORT_USERRFS = 0xEB;
public static final short ABORT_USERPND = 0xEC;
public static final short ABORT_USERDCR = 0xED;
public static final short ABORT_USERDCU = 0xEE;
static Logger logger = Logger.getLogger(CWSPSession.class);
public String[] states = {
"STATE_NULL", "STATE_CONNECTING", "STATE_CONNECTED", "STATE_SUSPENDED",
"STATE_RESUMING"
};
private boolean isSuspended = false;
private short suspendCode;
private boolean isDisconnected = false;
private short disconnectCode;
/**
* the actual session state
*/
private short state = STATE_NULL;
/**
* the acual transaction concering the session management
*/
private IWTPTransaction wtp;
/**
* the Layer below
*/
private CWTPSocket socket;
/**
* Holds all pending CWSPMethodManagers of this session
*/
private Vector methods = new Vector();
/**
* Holds all pending CWSPPushManagers of this session
*/
private Vector pushes = new Vector();
private IWSPUpperLayer upperlayer;
//////////////////////////////////////////////////////////////////////////////
////////////////////////////// Protocol parameters and variables - sect. 7.1.3
/**
* Maximum Receive Unit (sect. 7.1.3.1)
*/
private int MRU = 1400;
/**
* Maximum Outstanding Method Requests (sect. 7.1.3.2)
*/
private int MOM = 1;
/**
* Maximum Outstanding Push Requests (sect. 7.1.3.3)
*/
private int MOP = 1;
/**
* keeps track of the number of push transactions in process in the client
* (sect. 7.1.4.2)
*/
// pushs.size();
/**
* saves the session identifier (sect. 7.1.4.3)
* We will get this from the ConnectReply by the Server
*/
private long session_id = 0;
/**
* do we use IWSPUpperLayer2 or
*/
private byte version = 0;
//////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////// CONSTRUCTOR
public CWSPSession(InetAddress toAddress, int toPort,
IWSPUpperLayer upperLayer, boolean verbose) throws SocketException {
if ((upperLayer != null) && upperLayer instanceof IWSPUpperLayer2) {
this.version = 2;
} else {
this.version = 1;
}
// Make sure that the logging system is initialized
Logger.initLogSystem(verbose);
this.upperlayer = upperLayer;
socket = new CWTPSocket(toAddress, toPort, this);
// there can not be any session with the same peer address quadruplet!
}
public CWSPSession(InetAddress toAddress, int toPort,
IWSPUpperLayer upperLayer) throws SocketException {
this(toAddress, toPort, upperLayer, false);
}
public CWSPSession(CWSPSocketAddress address, IWSPUpperLayer upperLayer,
boolean verbose) throws SocketException {
this(address.getAddress(), address.getPort(), upperLayer, verbose);
}
//////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////// WSP service primitives - S-*.*
/**
* S-Connect.req
* @throws IOException Thrown, if Socket can not be opened.
*/
public synchronized void s_connect() {
if (state == STATE_NULL) {
abortAllMethods(ABORT_DISCONNECT);
abortAllPushes(ABORT_DISCONNECT);
// prepare WSP Connect PDU
CWSPConnect pdu = new CWSPConnect();
// prepare WTP Service Primitive
CWTPEvent initPacket = new CWTPEvent(pdu.toByteArray(),
CWTPEvent.TR_INVOKE_REQ);
// construct transaction with initPacket
wtp = socket.tr_invoke(this, initPacket, false,
IWTPTransaction.CLASS_TYPE_2);
setState(STATE_CONNECTING);
}
}
/**
* S-Disconnect.req
* @return S-Disconnect.ind
*/
public synchronized void s_disconnect() {
if (state == STATE_CONNECTING) {
wtp.abort(ABORT_DISCONNECT);
abortAllMethods(ABORT_DISCONNECT);
s_disconnect_ind(ABORT_USERREQ);
setState(STATE_NULL);
} else if (state == STATE_CONNECTED) {
abortAllMethods(ABORT_DISCONNECT);
abortAllPushes(ABORT_DISCONNECT);
CWSPDisconnect pdu = new CWSPDisconnect(session_id);
CWTPEvent initPacket = new CWTPEvent(pdu.toByteArray(),
CWTPEvent.TR_INVOKE_REQ);
wtp = socket.tr_invoke(this, initPacket, false,
IWTPTransaction.CLASS_TYPE_0);
s_disconnect_ind(ABORT_USERREQ);
setState(STATE_NULL);
} else if (state == STATE_SUSPENDED) {
s_disconnect_ind(ABORT_USERREQ);
setState(STATE_NULL);
} else if (state == STATE_RESUMING) {
wtp.abort();
abortAllMethods(ABORT_DISCONNECT);
s_disconnect_ind(ABORT_USERREQ);
setState(STATE_NULL);
}
socket.close();
}
/**
* S-Suspend.req
* @return S-Suspend.ind
*/
public synchronized boolean s_suspend() {
if (state == STATE_CONNECTED) {
abortAllMethods(ABORT_SUSPEND);
abortAllPushes(ABORT_SUSPEND);
CWSPSuspend pdu = new CWSPSuspend(this.session_id);
CWTPEvent initPacket = new CWTPEvent(pdu.toByteArray(),
CWTPEvent.TR_INVOKE_REQ);
wtp = socket.tr_invoke(this, initPacket, false,
IWTPTransaction.CLASS_TYPE_0);
s_disconnect_ind(ABORT_USERREQ);
setState(STATE_SUSPENDED);
return true;
} else if (state == STATE_RESUMING) {
wtp.abort(ABORT_SUSPEND);
abortAllMethods(ABORT_SUSPEND);
CWSPSuspend pdu = new CWSPSuspend(this.session_id);
CWTPEvent initPacket = new CWTPEvent(pdu.toByteArray(),
CWTPEvent.TR_INVOKE_REQ);
wtp = socket.tr_invoke(this, initPacket, false,
IWTPTransaction.CLASS_TYPE_0);
s_disconnect_ind(ABORT_USERREQ);
setState(STATE_NULL);
return true;
}
return false;
}
/**
* S-Resume.req
*/
public synchronized void s_resume() throws SocketException {
if (state == STATE_CONNECTED) {
abortAllMethods(ABORT_USERREQ);
abortAllPushes(ABORT_USERREQ);
// bind session to the new peer address quadruplet
socket.close();
socket = new CWTPSocket(socket.getRemoteAddress(),
socket.getRemotePort(), this);
CWSPResume pdu = new CWSPResume(session_id);
CWTPEvent initPacket = new CWTPEvent(pdu.toByteArray(),
CWTPEvent.TR_INVOKE_REQ);
wtp = socket.tr_invoke(this, initPacket, false,
IWTPTransaction.CLASS_TYPE_2);
setState(STATE_RESUMING);
} else if (state == STATE_SUSPENDED) {
CWSPResume pdu = new CWSPResume(session_id);
CWTPEvent initPacket = new CWTPEvent(pdu.toByteArray(),
CWTPEvent.TR_INVOKE_REQ);
wtp = socket.tr_invoke(this, initPacket, false,
IWTPTransaction.CLASS_TYPE_2);
setState(STATE_RESUMING);
}
}
/**
* Use this method to construct a POST-MethodInvoke.req.
* This method uses <code>methodInvoke(CWSPPDU pdu)</code>
* to send the constructed WSP-POST-PDU.
*
* @param data The data to be POSTed
* @param contentType The MIME-ContentType of the data to be POSTed
*/
public synchronized CWSPMethodManager s_post(byte[] data,
String contentType, String uri) {
/** @todo hier m黶sen die Nachrichten aufgeteilt werden !!!! */
CWSPPost pdu = new CWSPPost(data, contentType, uri);
return s_methodInvoke(pdu);
}
/**
* Use this method to construct a POST-MethodInvoke.req.
* This method uses <code>methodInvoke(CWSPPDU pdu)</code>
* to send the constructed WSP-POST-PDU.
*
* @param headers The headers defined for the request
* @param data The data to be POSTed
* @param contentType The MIME-ContentType of the data to be POSTed
* @param uri the target URI to post to
*/
public synchronized CWSPMethodManager s_post(CWSPHeaders headers,
byte[] data, String contentType, String uri) {
/** @todo hier m黶sen die Nachrichten aufgeteilt werden !!!! */
CWSPPost pdu = new CWSPPost(data, contentType, uri);
pdu.setHeaders(headers);
return s_methodInvoke(pdu);
}
/**
* Use this method to construct a GET-MethodInvoke.req.
* This method uses <code>methodInvoke(CWSPPDU pdu)</code>
* to send the constructed WSP-GET-PDU.
*
* @param uri The Unfied Resource Identifier of the resource to GET
*/
public synchronized CWSPMethodManager s_get(String uri) {
CWSPGet pdu = new CWSPGet(uri);
return s_methodInvoke(pdu);
}
/**
* Use this method to construct a GET-MethodInvoke.req.
* This method uses <code>methodInvoke(CWSPPDU pdu)</code>
* to send the constructed WSP-GET-PDU.
*
* @param headers The headers that are defined for the request
* @param uri The Unfied Resource Identifier of the resource to GET
*/
public synchronized CWSPMethodManager s_get(CWSPHeaders headers, String uri) {
CWSPGet pdu = new CWSPGet(uri);
pdu.setHeaders(headers);
return s_methodInvoke(pdu);
}
/**
* S-MethodInvoke.req
* To construct a POST- or GET-Request please use
* <code>get(String uri)</code> or
* <code>post(byte[] data, String contentType)</code>
* instead of this method.
*
* @param pdu The GET- or POST-PDU to be sent.
*/
public synchronized CWSPMethodManager s_methodInvoke(CWSPPDU pdu) {
if ((state != STATE_NULL) && (state != STATE_SUSPENDED)) {
CWSPMethodManager m = new CWSPMethodManager(pdu, this, upperlayer);
methods.add(m);
return m;
} else {
return null;
}
}
// s-methodInvokeData implemented in CWTPMethodManager
// s-methodResult implemented in CWTPMethodManager
// s-methodResultData implemented in CWTPMethodManager
// s-methodAbort.req implemented in CWTPMethodManager
// S-confirmedPush.res implemented in CWSPPushManager
// s_pushAbort.req implemented in CWSPPushManager
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -