|
- /**
- * @file ARQ.java
- *
- * @author Christos Choutouridis AEM:8997
- * @email cchoutou@ece.auth.gr
- */
- package net.hoo2.auth.vmodem;
-
- /** @name imports */
- /** @{ */
- import java.util.*;
- /** @} */
-
- /**
- * @class ARQ
- *
- * Class to used for the ACK-NACK sequence
- */
- class ARQ {
- static final int ARQ_DURATION_DEFAULT = 240; /** Default duration for the sequence */
- static final int ARQ_BUFFER_SIZE = 256; /** ARQ buffer size */
- static final String ARQ_BEGIN = "PSTART"; /** Begin pattern of the response */
- static final String ARQ_END = "PSTOP"; /** End pattern of the response */
-
- static final int ARQ_SEQUENCE_BEGIN = 31; /** The response sequence string position */
- static final int ARQ_SEQUENCE_END = 47; /** The end of response sequence string position */
- static final int ARQ_CRC_BEGIN = 49; /** The response crc string position */
- static final int ARQ_CRC_END = 52; /** The end of response crc string position */
-
- private Com com_; /** Reference to communication module */
- private Log log_; /** Reference to logging module */
- private Transaction transaction_; /** A transaction object to used as a buffer for all requests */
- private int duration_; /** The desired duration for the session */
- private byte[] ack_; /** The desired ACK code for the session */
- private byte[] nack_; /** The desired NACK code for the session */
-
- /**
- * Basic constructor
- * @param com The Com module to use
- * @param log The Log module to use
- * @param ack The desired ACK code
- * @param nack The desired NACK code
- * @param duration The desired duration for the session
- */
- ARQ (Com com, Log log, byte[] ack, byte[] nack, int duration) {
- com_ = com;
- log_ = log;
- duration_ = duration;
- transaction_= new Transaction(null, new byte[ARQ_BUFFER_SIZE]);
- ack_ = ack;
- nack_ = nack;
- }
-
- /**
- * Functionality to drain the response buffer for the welcome message
- * from the server
- * @param ack The ack code that we will use (for printing, not sending)
- * @param nack The nack code that we will use (for printing, not sending)
- */
- void caption (byte[] ack, byte[] nack) {
- String line;
-
- line = "Running ARQ with: " + new String(ack) + "/" + new String(nack);
- log_.write(line, true);
-
- transaction_ = com_.request (transaction_, null, null, null, false);
- line = new String(transaction_.getResponse());
- log_.out(line);
- }
-
- /**
- * Main transaction loop. It send requests to server, get the response
- * and log the procedure while doing it.
- */
- void run () {
- long start;
- long now;
- long mark =0, tr =0, ts =0, tt =0;
- String line;
- int errors = 0;
- boolean good = true;
-
- start = System.currentTimeMillis();
- do {
- // Check if the previous transaction was error-free
- if (good)
- transaction_ = com_.request(transaction_, ack_, ARQ_BEGIN.getBytes(), ARQ_END.getBytes(), false);
- else
- transaction_ = com_.request(transaction_, nack_, ARQ_BEGIN.getBytes(), ARQ_END.getBytes(), false);
- good = (_crc_check(transaction_.response)) ? true : false; // crc check the response
-
- // time calculations
- tr = transaction_.arrival - transaction_.departure;
- tt = 0;
- if ((errors == 0) && good) {
- tt = ts = tr;
- }
- if ((errors == 0) && !good) {
- mark = transaction_.departure;
- ts = tr;
- }
- if ((errors != 0) && good) {
- tt = transaction_.arrival - mark;
- ts += tr;
- }
- if ((errors !=0) && !good) {
- ts += tr;
- }
- errors = (good) ? 0 : errors+1; // update the error strike
-
- line = new String(transaction_.code) + ": "
- + new String(transaction_.getResponse())
- + " Er: " + errors
- + " Tr= " + tr + " [msec]";
- if (errors !=0)
- line += " Ts= 0 [msec] Tt= 0 [msec]";
- else
- line += " Ts= " + ts + " [msec]" + " Tt= " + tt + " [msec]";
-
- log_.write(line);
- now = System.currentTimeMillis();
- } while (now - start < duration_*1000);
- }
-
- /** @name private helper API */
- /**@{ */
-
- /**
- * A CRC check functionality
- * @param data The data to check for validity
- * @return The check result
- */
- private boolean _crc_check (byte[] data) {
- byte[] seq = Arrays.copyOfRange(data, ARQ_SEQUENCE_BEGIN, ARQ_SEQUENCE_END);
- int crc = Integer.valueOf(
- new String(Arrays.copyOfRange(data, ARQ_CRC_BEGIN, ARQ_CRC_END))
- );
- return (crc == _crc(seq)) ? true : false;
- }
-
- /**
- * A CRC calculation function. This primitive CRC calculator
- * does not use any known CRC polynomial. It just uses XOR
- * @param data Reference to buffer
- * @return The CRC result
- */
- private int _crc (byte[] data) {
- int calc =0;
- for (int i=0 ; i<data.length ; ++i)
- calc ^= data[i];
- return calc;
- }
- /**@} */
- }
|