📄 cwtpinitiator.java
字号:
segdata.write(res.getPayload()); } catch (IOException e) { logger.warn("Exception writing to ByteArrayOutputStream",e); } nextState=STATE_RESULT_WAIT; // We will wait for more to come } setState(nextState); // if !holdOn generate TR_Invoke.cnf if(!holdOn) { upperLayer.tr_process( new CWTPEvent(pdu.getPayload(), CWTPEvent.TR_INVOKE_CNF)); } if( !res.getTTR() && res.getGTR() ) { byte payload[] = new byte[2]; CWTPAck ack = new CWTPAck(sendTID); payload[0] = (0x03 << 3) | 0x01; // psn, one byte length payload[1] = 0; // Implicit sequence number 0 ack.setCON(true); // headers follow ;) ack.setPayload(payload); if(logger.isDebugEnabled()) { logger.debug("sending ack:" + ack.toString()); } wtpSocket.send(ack); } if( nextState != STATE_RESULT_WAIT ) { // generate tr_result.ind upperLayer.tr_process( new CWTPEvent(pdu.getPayload(), CWTPEvent.TR_RESULT_IND)); } // restart ack timer a_timer.restart(); } else if (pdu.getPDUType() == CWTPPDU.PDU_TYPE_SEGM_RESULT) { logger.debug("Segmented result"); boolean sendAck = false; boolean sendToUpper = false; CWTPSegmResult sres = (CWTPSegmResult) pdu; w_timer.restart(); a_timer.restart(); if (sres.getTID() != segTID) { logger.warn("Dumping out-of sync segment from outer space!"); return; } if (seglast + 1 == sres.getPSN()) { // we are in line with stuff seglast = sres.getPSN(); try { segdata.write(sres.getPayload()); } catch (IOException e) { logger.warn("Exception writing to ByteArrayOutputStream",e); } if (sres.getGTR()) { logger.debug("Last packet of packet group"); // ==> ttr must be 0 -> end of group sendAck = true; } else if (sres.getTTR()) { logger.debug("Last packet of message"); // EOF :) sendAck = true; sendToUpper = true; setState(STATE_RESULT_RESP_WAIT); } //else not last packet... } else { logger.warn( "LOST PACKET - last " + seglast + " current psn " + sres.getPSN()); // @todo: send NACK } if (sendAck) { byte payload[] = new byte[2]; CWTPAck send = new CWTPAck(sendTID); payload[0] = (0x03 << 3) | 0x01; // psn, one byte length payload[1] = (byte) (0x7f & sres.getPSN()); send.setCON(true); // headers follow ;) send.setPayload(payload); if(logger.isDebugEnabled()) { logger.debug("sending ack:" + send.toString()); } wtpSocket.send(send); } if (sendToUpper) { byte[] payload = segdata.toByteArray(); upperLayer.tr_process(new CWTPEvent(payload, CWTPEvent.TR_RESULT_IND)); segdata = null; segend = 0; } } break; ///////////////////// RESULT RESP WAIT ////////////////////////////////// case 0x02: // RcvAbort in RESULT RESP WAIT if (pdu.getPDUType() == CWTPPDU.PDU_TYPE_ABORT) { short abortReason = ((CWTPAbort) pdu).getAbortReason(); close(abortReason); upperLayer.tr_abort(abortReason); setState(STATE_NULL); } // RcvResult in RESULT RESP WAIT else if (pdu.getPDUType() == CWTPPDU.PDU_TYPE_RESULT) { logger.debug("blp"); setState(STATE_RESULT_RESP_WAIT); // RcvSegmResult in RESULT RESP WAIT } else if (pdu.getPDUType() == CWTPPDU.PDU_TYPE_SEGM_RESULT) { logger.debug("XXXXXX blpseg"); setState(STATE_RESULT_RESP_WAIT); } break; ///////////////////// WAIT TIMEOUT ////////////////////////////////////// case 0x03: // RcvAbort in WAIT TIMEOUT if (pdu.getPDUType() == CWTPPDU.PDU_TYPE_ABORT) { short abortReason = ((CWTPAbort) pdu).getAbortReason(); close(abortReason); upperLayer.tr_abort(abortReason); setState(STATE_NULL); } // RcvResult in WAIT TIMEOUT else if (pdu.getPDUType() == CWTPPDU.PDU_TYPE_RESULT) { if (pdu.getRID()) { /** @todo input TPI exitinfo if available - page 54 **/ CWTPAck send = new CWTPAck(sendTID); wtpSocket.send(send); setState(STATE_WAIT_TIMEOUT); } else { setState(STATE_WAIT_TIMEOUT); } } break; ///////////////////// WAIT ACK WHILE SEGMENTATION SENDING //////////////// case 0x04: // rcvAck in STATE_WAIT_ACK if (pdu.getPDUType() == CWTPPDU.PDU_TYPE_ACK) { //re-initialize re-sending counter s_timer.stop(); segment_sended = 1; segment = null; // send next segment pdu = (CWTPPDU) (sentPDU.getSegments().elementAt(segmentIndex)); wtpSocket.send(pdu); segmentIndex++; // last segment sent if (sentPDU.getSegments().size() == segmentIndex) { segmentIndex = 0; if ((classType == 1) | (classType == 2)) { // start timer to re-send whole message r_timer.restart(); setState(STATE_RESULT_WAIT); } else if (classType == 0) { setState(STATE_NULL); close((short) 0x00); } } // not last segment else { // save segment for re-sending segment = pdu; // start timer to re-send segment s_timer.restart(); } } break; } } /** * Invoked by higher layers to process given service primitives * according to state machine described in section 9.5.<br> * <b>Notice:</b> Only WTP Initiator is implemented! * * @param p the Service Primitive to be processed */ public synchronized void process(CWTPEvent p) throws EWTPAbortedException { if (aborted) { throw new EWTPAbortedException(abortCode); } if (logger.isDebugEnabled()) { logger.debug("" + sendTID + ": " + CWTPEvent.types[p.getType()] + " in " + states[state]); } switch (state) { ///////////////////// STATE NULL ///////////////////////////////////////// case 0x00: // TR-INVOKE.REQ // some things do do when receiving a TR-Invoke // were already done in the constructor - so please see there! if (p.getType() == CWTPEvent.TR_INVOKE_REQ) { if (((classType == 1) | (classType == 2)) && uack) { CWTPInvoke send = new CWTPInvoke(p.getUserData(), sendTID, classType); wtpSocket.addTransaction(this); wtpSocket.send(send); sentPDU = send; this.rcr = 0; r_timer.restart(); setState(STATE_RESULT_WAIT); } else if (((classType == 1) | (classType == 2)) && !uack) { CWTPInvoke send = new CWTPInvoke(p.getUserData(), sendTID, classType); wtpSocket.addTransaction(this); wtpSocket.send(send); sentPDU = send; this.rcr = 0; // do we have to segmentate? if (!send.getTTR()) { setState(STATE_WAIT_ACK); } else { r_timer.restart(); setState(STATE_RESULT_WAIT); } } else if (classType == 0) { CWTPInvoke send = new CWTPInvoke(p.getUserData(), sendTID, classType); wtpSocket.addTransaction(this); wtpSocket.send(send); // do we have to segmentate? if (!send.getTTR()) { sentPDU = send; setState(STATE_WAIT_ACK); } else { setState(STATE_NULL); close((short) 0x00); } } } //end TR-INVOKE.REQ break; //////////////////// STATE RESULT WAIT /////////////////////////////////// case 0x01: break; ///////////////////// STATE RESULT RESP WAIT ///////////////////////////// case 0x02: // TR-Result.res if (p.getType() == CWTPEvent.TR_RESULT_RES) { if (p.getExitInfo().length != 0) { CWTPAck send = new CWTPAck(sendTID); /** @todo input TPI exitinfo into "send" - page 54 top **/ wtpSocket.send(send); w_timer.restart(); setState(STATE_WAIT_TIMEOUT); } else { CWTPAck send = new CWTPAck(sendTID); wtpSocket.send(send); w_timer.restart(); setState(STATE_WAIT_TIMEOUT); } } // end TR-Result.res break; ///////////////////// STATE WAIT TIMEOUT ///////////////////////////////// case 0x03: break; } } public void process(EWTPCorruptPDUException e) { if (state != STATE_NULL) { CWTPAbort send = new CWTPAbort(e.getTid()); send.setAbortReason(CWTPAbort.ABORT_REASON_PROTOERR); wtpSocket.send(send); close(CWTPAbort.ABORT_REASON_PROTOERR); upperLayer.tr_abort(CWTPAbort.ABORT_REASON_PROTOERR); setState(STATE_NULL); } } /** * use this method to invoke a TR-ABORT.REQ by the upper Layer */ public void abort() { abort(CWTPAbort.ABORT_REASON_UNKNOWN); } /** * use this method to invoke a TR-ABORT.REQ by the upper Layer */ public void abort(short abortReason) { // TR-ABORT.REQ if ((state == 0x01) || (state == 0x02) || (state == 0x03)) { if(logger.isDebugEnabled()) { logger.debug("" + sendTID + ": TR-ABORT.REQ Reason: " + abortReason); } CWTPAbort send = new CWTPAbort(sendTID); send.setAbortReason(abortReason); wtpSocket.send(send); close(abortReason); } } public void close(short reasonCode) { abortCode = reasonCode; aborted = true; r_timer.stop(); w_timer.stop(); a_timer.stop(); setState(STATE_NULL); wtpSocket.removeTransaction(this); } //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX //XXXXXXXXXXXXXXXXXXXXXX SET/GET XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX /* public boolean getAckType(){ return uack; } public void setAckType(boolean ackType){ uack = ackType; } public IWTPUpperLayer getUpperLayer(){ return upperLayer; } */ public int getTID() { return sendTID; } public void setClassType(byte classType) throws IllegalArgumentException { if ((classType == 1) | (classType == 2) | (classType == 0)) { this.classType = classType; return; } else { throw new IllegalArgumentException("Class Type has to be 1, 2 or 3"); } } public byte getClassType() { return classType; } private void setState(byte state) { //if (debug){ // log.log(0, this, "" + sendTID + ": " + states[this.state] + " >>> " + states[state]); //} this.state = state; } public boolean isAborted() { return aborted; } public short getAbortCode() { return abortCode; } //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX /** * Static method, that generates a new (unique) Transaction ID * by incrementing genTID * * @return A new unique Transaction ID */ private static synchronized int generateNewTID() { if (genTID == -1) { Random r = new Random(); genTID = Math.abs(r.nextInt() % 255); } int result = genTID; if (genTID == 255) { genTID = 0; } else { ++genTID; } return result; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -