⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cwspsession.java

📁 WAP协议栈的JAVA实现
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/**
 * 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 + -