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

📄 cwtpresponder.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.wtp;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import net.sourceforge.jwap.util.Logger;
import net.sourceforge.jwap.wtp.pdu.CWTPAbort;
import net.sourceforge.jwap.wtp.pdu.CWTPAck;
import net.sourceforge.jwap.wtp.pdu.CWTPInvoke;
import net.sourceforge.jwap.wtp.pdu.CWTPPDU;
import net.sourceforge.jwap.wtp.pdu.CWTPResult;
import net.sourceforge.jwap.wtp.pdu.EWTPCorruptPDUException;


public class CWTPResponder implements IWTPTransaction{

  private static final byte STATE_LISTEN = 0x00;
  private static final byte STATE_TIDOK_WAIT = 0x01;
  private static final byte STATE_INVOKE_RESP_WAIT = 0x02;
  private static final byte STATE_RESULT_WAIT = 0x03;
  private static final byte STATE_RESULT_RESP_WAIT = 0x04;
  private static final byte STATE_WAIT_TIMEOUT = 0x05;

  private static final String[] states = {"LISTEN",
                                          "TIDOK WAIT",
                                          "INVOKE RESP WAIT",
                                          "RESULT WAIT",
                                          "RESLUT RESP WAIT",
                                          "WAIT TIMEOUT"};

  static Logger logger = Logger.getLogger(CWTPResponder.class);

  private byte state = 0x00;

  // which session does this transaction belong to?
  private IWTPUpperLayer upperLayer;

  // used to send and receive
  private CWTPSocket wtpSocket;

  // is this transaction aborted?
  private boolean aborted = false;
  private short abortCode;

  /**
   * 5.3.1.7
   * Class Type 1, 2 or 3
   */
  private byte classType;

  /**
   * 9.4.1
   * ack interval
   * this sets a bound for the amount of time to wait before sending an acknowledgement.
   */
  private javax.swing.Timer a_timer;
  private int a = 5000;

  /**
   * 9.4.1
   * retry interval
   * This sets a bound for the amount of time to wait before re-transmitting a PDU.
   */
  private javax.swing.Timer r_timer;
  private int r = 10000;

  /**
   * 9.4.1
   * wait timeout interval (only class 2 initiator and class 1 responder)
   * This sets a bound for the amount of time to wait before state information
   * about a transaction is released.
   */
  private javax.swing.Timer w_timer;
  private int w = 5000;

  /**
   * 9.4.2
   * re-transmission counter
   * acknowledgement expireation counter
   */
  private int rcr = 0;
  private int aec = 0;

  public static final int RCR_MAX = 3;
  public static final int AEC_MAX = 3;

  /**
   * 9.4.3
   * counter to generate unique TIDs
   * uint16
   */
  private static int genTID = 0;

  /**
   * uint16
   */
  private int sendTID;
  private int rcvTID;
  private int lastTID;

  /**
   * recently sent PDU - hold it for retransmission
   */
  private CWTPPDU sentPDU;

  private boolean holdOn = false;
  private boolean uack = false;


  //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  //XXXXXXXXXXXXXXXXXXXXXXX CONSTRUCTOR XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  /**
   * Constructs a CWTPSocket using a DatagramSocket (UDP).
   * Even implementing all parameters belonging to according to
   * TR-Invoke service primitive (section 5.3.1),
   * which are not temporary for one transaction.
   * This socket can be used several times by service primitives.
   * After all it has to be closed by calling <code>close()</code>
   *
   * @see #close(short)
   * @param to destination address (section 5.3.1.3)
   * @param port destination port (section 5.3.1.4)
   * @param ackType Ack Type (section 5.3.1.5)
   * @param classType Class Type (0, 1 or 2) (section 5.3.1.8)
   * @throws IllegalArgumentException
   * @throws SocketException
   */
  public CWTPResponder(CWTPSocket wtp_Socket,
                        IWTPUpperLayer upper_Layer,
                        CWTPInvoke initPDU,
                        boolean ackType,
                        byte classtype
                        ){
    init(wtp_Socket, upperLayer, ackType, classtype);

    rcvTID = initPDU.getTID();
    sendTID = rcvTID - 32768; // sendTID = rcvTID XOR 0x8000

    // process the invoke pdu
    try{
      process(initPDU);
    } catch (EWTPAbortedException e){
      logger.error("PDU processing aborted", e);
    }
  }

  private void init(CWTPSocket wtp_Socket,
                    IWTPUpperLayer upper_Layer,
                    boolean ackType,
                    byte classtype
                  ) throws IllegalArgumentException {
    this.upperLayer = upper_Layer;
    this.wtpSocket = wtp_Socket;
    wtpSocket.addTransaction(this);
    uack = ackType;
    setClassType(classtype);

    // initialize timer and add actionListener
    // see declaration of a_timer above
    a_timer = new javax.swing.Timer(a,
      new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          a_timer.stop();
          if (state == STATE_INVOKE_RESP_WAIT){
            // check acknowledgement counter
            if (aec < AEC_MAX){
              logger.debug("acknowledgement timer abgelaufen: aec < AEC_MAX");

              aec++;
              a_timer.restart();
              setState(STATE_RESULT_RESP_WAIT);
            } else if (aec == AEC_MAX){
              //abort if acknowledgement counter exceeds the maximum
              logger.debug("acknowledgement timer abgelaufen: aec == AEC_MAX");


              CWTPAbort send = new CWTPAbort(sendTID);
              send.setAbortReason(CWTPAbort.ABORT_REASON_NORESPONSE);
              wtpSocket.send(send);
              close(CWTPAbort.ABORT_REASON_NORESPONSE);
              aec = 0;
              upperLayer.tr_abort(CWTPAbort.ABORT_REASON_NORESPONSE);
              setState(STATE_LISTEN);
            } else if (!uack && classType == CLASS_TYPE_1){
              logger.debug("acknowledgement timer abgelaufen: uack == false classtype 1");

              CWTPAck send = new CWTPAck(sendTID);
              wtpSocket.send(send);
              w_timer.restart();
              setState(STATE_WAIT_TIMEOUT);
            } else if (!uack && classType == CLASS_TYPE_2){
              logger.debug("acknowledgement timer abgelaufen: uack == false classtype 2");

              CWTPAck ack = new CWTPAck(sendTID);
              wtpSocket.send(ack);
              setState(STATE_RESULT_WAIT);
            }
          }
          else if (state == STATE_RESULT_WAIT){
            logger.debug("acknowledgement timer abgelaufen.");

            CWTPAck ack = new CWTPAck(sendTID);
            wtpSocket.send(ack);
            setState(STATE_RESULT_WAIT);
          }
        }
      }
    );

    // see declaration of r_timer above
    r_timer = new javax.swing.Timer(r,
      new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          r_timer.stop();
          if (state == STATE_RESULT_RESP_WAIT){
            // check retransmission counter
            if (rcr < RCR_MAX){
              logger.debug("retransmission timer "+ rcr
                            + " mal abgelaufen. Re-sending Result.");

              rcr++;
              r_timer.restart();
              // re-send recent Result
              wtpSocket.send(sentPDU);
              setState(STATE_RESULT_RESP_WAIT);
            } else if (rcr == RCR_MAX){
              logger.debug("retransmission timer " + rcr
                            + " mal abgelaufen. Abbruch!");

              // abort
              close(CWTPAbort.ABORT_REASON_UNKNOWN);
              upperLayer.tr_abort(CWTPAbort.ABORT_REASON_UNKNOWN);
              rcr = 0;
              setState(STATE_LISTEN);
            }
          }
        }
      }
    );

    // see declaration of w_timer above
    w_timer = new javax.swing.Timer(w,
      new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          w_timer.stop();
          if (state == STATE_WAIT_TIMEOUT){
            logger.debug("wait timeout");

            setState(STATE_LISTEN);
            close((short)0x00);
          }
        }
      }
    );
  }

  //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  /**
   * Invoked by the run()-Method of the Management-Entity CWTPManagement.
   * Processes given protocol data units
   * according to state machine described in section 9.5
   * <b>Notice:</b> Only WTP Initiator is implemented!
   *
   * @param pdu the pdu to be processed in the state machine
   */
  public synchronized void process(CWTPPDU pdu) throws EWTPAbortedException{
    if (aborted){
      throw new EWTPAbortedException(abortCode);
    }
    switch (state){
      ///////////////////// STATE LISTEN ///////////////////////////////////////
      case 0x00:
        // invoke pdu in state listen
        if(pdu.getPDUType() == CWTPPDU.PDU_TYPE_INVOKE){
          if (this.classType == IWTPTransaction.CLASS_TYPE_1 ||
              this.classType == IWTPTransaction.CLASS_TYPE_2){
            if (true/** @todo is tid ok? */){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -