Code comments
This commit is contained in:
父節點
b212aa07d4
當前提交
fb39a2633b
2
.gitignore
vendored
2
.gitignore
vendored
@ -2,3 +2,5 @@
|
||||
*.project
|
||||
*.classpath
|
||||
*.pdf
|
||||
*.doc
|
||||
|
||||
|
||||
未顯示二進位檔案。
未顯示二進位檔案。
未顯示二進位檔案。
未顯示二進位檔案。
未顯示二進位檔案。
未顯示二進位檔案。
未顯示二進位檔案。
未顯示二進位檔案。
14480
report/src/echo_home_2018-12-1-1759.csv
Normal file
14480
report/src/echo_home_2018-12-1-1759.csv
Normal file
檔案差異因為檔案過大而無法顯示
載入差異
@ -1,25 +1,47 @@
|
||||
/**
|
||||
* @file AQR.java
|
||||
*
|
||||
* @author Christos Choutouridis AEM:8997
|
||||
* @email cchoutou@ece.auth.gr
|
||||
*/
|
||||
package net.hoo2.auth.vmodem;
|
||||
|
||||
/** @name imports */
|
||||
/** @{ */
|
||||
import java.util.*;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @class AQR
|
||||
*
|
||||
* Class to used for the ACK-NACK sequence
|
||||
*/
|
||||
class AQR {
|
||||
static final int AQ_DURATION_DEFAULT = 240;
|
||||
static final int AQR_BUFFER_SIZE = 256;
|
||||
static final String AQR_BEGIN = "PSTART";
|
||||
static final String AQR_END = "PSTOP";
|
||||
static final int AQ_DURATION_DEFAULT = 240; /**< Default duration for the sequence */
|
||||
static final int AQR_BUFFER_SIZE = 256; /**< AQR buffer size */
|
||||
static final String AQR_BEGIN = "PSTART"; /**< Begin pattern of the response */
|
||||
static final String AQR_END = "PSTOP"; /**< End pattern of the response */
|
||||
|
||||
static final int AQR_SEQUENCE_BEGIN = 31;
|
||||
static final int AQR_SEQUENCE_END = 47;
|
||||
static final int AQR_CRC_BEGIN = 49;
|
||||
static final int AQR_CRC_END = 52;
|
||||
static final int AQR_SEQUENCE_BEGIN = 31; /**< The response sequence string position */
|
||||
static final int AQR_SEQUENCE_END = 47; /**< The end of response sequence string position */
|
||||
static final int AQR_CRC_BEGIN = 49; /**< The response crc string position */
|
||||
static final int AQR_CRC_END = 52; /**< The end of response crc string position */
|
||||
|
||||
private Com com_;
|
||||
private Log log_;
|
||||
private Transaction transaction_;
|
||||
private int duration_;
|
||||
private byte[] ack_;
|
||||
private byte[] nack_;
|
||||
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
|
||||
*/
|
||||
AQR (Com com, Log log, byte[] ack, byte[] nack, int duration) {
|
||||
com_ = com;
|
||||
log_ = log;
|
||||
@ -28,7 +50,13 @@ class AQR {
|
||||
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;
|
||||
|
||||
@ -40,6 +68,10 @@ class AQR {
|
||||
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;
|
||||
@ -51,12 +83,13 @@ class AQR {
|
||||
|
||||
start = System.currentTimeMillis();
|
||||
do {
|
||||
// Check if the previous transaction was error-free
|
||||
if (good)
|
||||
transaction_ = com_.request(transaction_, ack_, AQR_BEGIN.getBytes(), AQR_END.getBytes(), false);
|
||||
else
|
||||
transaction_ = com_.request(transaction_, nack_, AQR_BEGIN.getBytes(), AQR_END.getBytes(), false);
|
||||
good = (_crc_check(transaction_.response)) ? true : false;
|
||||
bads = (good) ? 0 : bads+1;
|
||||
good = (_crc_check(transaction_.response)) ? true : false; // crc check the response
|
||||
bads = (good) ? 0 : bads+1; // count the error strike
|
||||
|
||||
// delay calculation
|
||||
if (prev && !good) mark = transaction_.departure;
|
||||
@ -73,18 +106,33 @@ class AQR {
|
||||
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, AQR_SEQUENCE_BEGIN, AQR_SEQUENCE_END);
|
||||
int crc = Integer.valueOf(
|
||||
new String(Arrays.copyOfRange(data, AQR_CRC_BEGIN, AQR_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;
|
||||
}
|
||||
/**@} */
|
||||
}
|
||||
|
||||
@ -1,17 +1,35 @@
|
||||
/**
|
||||
* @file Com.java
|
||||
*
|
||||
* @author Christos Choutouridis AEM:8997
|
||||
* @email cchoutou@ece.auth.gr
|
||||
*/
|
||||
package net.hoo2.auth.vmodem;
|
||||
|
||||
/** @name imports */
|
||||
/** @{ */
|
||||
import java.util.Arrays;
|
||||
import ithakimodem.*;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @class Com
|
||||
*
|
||||
* Wrapper object of the provided Modem class to provide
|
||||
* a convenient and common API for all the session functionalities
|
||||
*/
|
||||
class Com {
|
||||
static final int SPEED_DEFAULT = 48000;
|
||||
static final int TIMEOUT_DEFAULT = 2000;
|
||||
static final String URL_DEFAULT = "ithaki";
|
||||
static final int SPEED_DEFAULT = 48000; /**< default communication speed [bps] */
|
||||
static final int TIMEOUT_DEFAULT = 2000; /**< default timeout values [sec] */
|
||||
static final String URL_DEFAULT = "ithaki"; /**< Default destination. Ithaki of-course */
|
||||
|
||||
private Modem modem_;
|
||||
private int speed_;
|
||||
private int timeout_;
|
||||
private Modem modem_; /**< Ref to Modem */
|
||||
private int speed_; /**< Communication speed [bps] */
|
||||
private int timeout_; /**< communication timeout [sec] */
|
||||
|
||||
/**
|
||||
* Basic constructor
|
||||
*/
|
||||
Com () {
|
||||
modem_ = new Modem();
|
||||
speed_ = SPEED_DEFAULT;
|
||||
@ -19,6 +37,14 @@ class Com {
|
||||
modem_.setSpeed(speed_);
|
||||
modem_.setTimeout(timeout_);
|
||||
}
|
||||
/** A more fancy constructor
|
||||
*
|
||||
* @param log Reference to Log to use
|
||||
* @param speed The desired speed [bps]
|
||||
* @param timeout The desired timeout [sec]
|
||||
* @note
|
||||
* Currently not used
|
||||
*/
|
||||
Com (Log log, int speed, int timeout) {
|
||||
modem_ = new Modem();
|
||||
speed_ = speed;
|
||||
@ -26,63 +52,96 @@ class Com {
|
||||
modem_.setSpeed(speed_);
|
||||
modem_.setTimeout(timeout_);
|
||||
}
|
||||
|
||||
// get/set
|
||||
|
||||
/** @name Mutator interface */
|
||||
/**@{ */
|
||||
/** Get the current timeout value [sec] */
|
||||
int timeout () { return timeout_; }
|
||||
/** Set the timeout value [sec] */
|
||||
void timeout (int timeout) {
|
||||
if (timeout_ != timeout) {
|
||||
timeout_ = timeout;
|
||||
modem_.setTimeout(timeout_);
|
||||
}
|
||||
}
|
||||
|
||||
/** Get the current speed [bps] */
|
||||
int speed () { return speed_; }
|
||||
/** Set the speed [bps] */
|
||||
void speed (int speed) {
|
||||
if (speed_ != speed) {
|
||||
speed_ = speed;
|
||||
modem_.setSpeed(speed_);
|
||||
}
|
||||
}
|
||||
|
||||
/**@} */
|
||||
|
||||
/** @name Public API of the class */
|
||||
/**@{ */
|
||||
/** Open a communication channel with a URL */
|
||||
boolean open (String url) { return modem_.open(url); }
|
||||
/** Open a communication channel with Ithaki */
|
||||
boolean open () { return modem_.open(URL_DEFAULT); }
|
||||
/** Close the connection */
|
||||
boolean close() { return modem_.close(); }
|
||||
|
||||
|
||||
/**
|
||||
* @grief The basic communication functionality
|
||||
*
|
||||
* This function sends a request to server and return the response. In order to
|
||||
* do that, the main reading loop seeks for the starting pattern and use the data
|
||||
* from that point up to the ending pattern. This is very helpful for binary incoming
|
||||
* data.
|
||||
* @note
|
||||
* Blocking mode
|
||||
* @param data Reference to Transaction data to use @see Transaction
|
||||
* @param code The request code to send
|
||||
* @param begin The starting pattern of the response data
|
||||
* @param end The ending pattern of the response data
|
||||
* @param bin A flag to indicate that the data are in binary form
|
||||
* @return Reference to Transaction object with the response data. @see Transaction
|
||||
*/
|
||||
Transaction request (Transaction data, byte[] code, byte[] begin, byte[] end, boolean bin) {
|
||||
int ch =0;
|
||||
boolean have_begin = (begin != null) ? false : true;
|
||||
boolean incoming = false;
|
||||
|
||||
// Clear the receive buffer first
|
||||
_clear (data.response, 0, data.response.length);
|
||||
if (code != null) {
|
||||
data.code = code;
|
||||
modem_.write(data.code);
|
||||
// if we have a request
|
||||
data.code = code; // store the request code for the transaction
|
||||
modem_.write(data.code); // send the code and mark the time
|
||||
modem_.write((int)'\r');
|
||||
data.departure = System.currentTimeMillis();// - (long)((8*(data.code.length+1))*(1000.0/speed_));
|
||||
}
|
||||
|
||||
// main receive loop
|
||||
data.size =0;
|
||||
do {
|
||||
// escape guard for memory protection
|
||||
if (data.size >= data.response.length) {
|
||||
data.size =0;
|
||||
return data;
|
||||
}
|
||||
// read the data byte from server
|
||||
try {
|
||||
ch = modem_.read();
|
||||
}
|
||||
catch (Exception e) {
|
||||
// Oops!!!! something went wrong. Break and return :(
|
||||
System.err.println (e.getMessage());
|
||||
data.size =0;
|
||||
return data;
|
||||
}
|
||||
if (!incoming) {
|
||||
// first byte triggered. mark the time
|
||||
incoming = true;
|
||||
data.arrival = System.currentTimeMillis();// - (long)(8*(1000.0/speed_));
|
||||
}
|
||||
data.response [data.size++] = (byte)ch;
|
||||
data.response [data.size++] = (byte)ch; // store the byte
|
||||
|
||||
if (!have_begin && (detect(data.response, begin, data.size) != -1)) {
|
||||
// If begin pattern detected, start over.
|
||||
_clear(data.response, 0, data.size);
|
||||
data.size = _copy (data.response, begin);
|
||||
have_begin = true;
|
||||
@ -95,9 +154,28 @@ class Com {
|
||||
)
|
||||
)
|
||||
);
|
||||
/*^
|
||||
* We loop until:
|
||||
* 1) server returns -1
|
||||
* 2) A end pattern arrives
|
||||
* 3) A "\r\n\n\n" sequence arrives (in character mode, not for binary files)
|
||||
* 4) A "NO CARRIER" sequence arrives (in character mode, not for binary files)
|
||||
*/
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* A pattern detect functionality.
|
||||
*
|
||||
* Search in data input for the pattern and return its position if found.
|
||||
* @note
|
||||
* O(n^2) in time.
|
||||
* @param data The data buffer to search into
|
||||
* @param pattern The pattern to search for
|
||||
* @param max The maximum length to search
|
||||
* @return The position of pattern in data, or -1 if not found
|
||||
*/
|
||||
static int detect (byte[] data, byte[] pattern, int max) {
|
||||
if (pattern != null) {
|
||||
for (int i =0 ; i<max && i<data.length - pattern.length; ++i) {
|
||||
@ -114,12 +192,27 @@ class Com {
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
/**@} */
|
||||
|
||||
/** @name Private helper api */
|
||||
/**@{*/
|
||||
/**
|
||||
* Clear a buffer segment
|
||||
* @param buffer Buffer to clear
|
||||
* @param begin The starting point
|
||||
* @param end The ending point
|
||||
*/
|
||||
private void _clear (byte[] buffer, int begin, int end) {
|
||||
for (int i=begin ; i<end && i<buffer.length ; ++i)
|
||||
buffer[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy a buffer to another
|
||||
* @param dest The destination buffer
|
||||
* @param src The source buffer
|
||||
* @return The number of bytes copied
|
||||
*/
|
||||
private int _copy (byte[] dest, byte[] src) {
|
||||
if (dest.length >= src.length) {
|
||||
for (int i=0 ; i<src.length ; ++i)
|
||||
@ -128,24 +221,35 @@ class Com {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**@}*/
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @class
|
||||
* Class to represent client-server transaction data
|
||||
*/
|
||||
class Transaction {
|
||||
byte[] code;
|
||||
byte[] response;
|
||||
long departure;
|
||||
long arrival;
|
||||
int size;
|
||||
|
||||
byte[] code; /**< request code from client */
|
||||
byte[] response; /**< response data from server */
|
||||
long departure; /**< request time */
|
||||
long arrival; /**< response time */
|
||||
int size; /**< size of response data in bytes */
|
||||
|
||||
/**
|
||||
* Basic constructor
|
||||
* @param code Code to use
|
||||
* @param response Response buffer to use
|
||||
*/
|
||||
Transaction (byte[] code, byte[] response) {
|
||||
this.code = code;
|
||||
this.response = response;
|
||||
departure = arrival = 0;
|
||||
size = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a copy of the response
|
||||
*/
|
||||
byte[] getResponse() {
|
||||
return Arrays.copyOf(response, size);
|
||||
}
|
||||
|
||||
@ -1,25 +1,49 @@
|
||||
/**
|
||||
* @file Echo.java
|
||||
*
|
||||
* @author Christos Choutouridis AEM:8997
|
||||
* @email cchoutou@ece.auth.gr
|
||||
*/
|
||||
package net.hoo2.auth.vmodem;
|
||||
|
||||
/**
|
||||
* @class Echo
|
||||
*
|
||||
* Class to used for the echo sequence
|
||||
*/
|
||||
class Echo {
|
||||
static final int ECHO_DURATION_DEFAULT = 240;
|
||||
static final int ECHO_BUFFER_SIZE = 256;
|
||||
static final String ECHO_BEGIN = "PSTART";
|
||||
static final String ECHO_END = "PSTOP";
|
||||
static final int ECHO_DURATION_DEFAULT = 240; /**< Default duration for the sequence */
|
||||
static final int ECHO_BUFFER_SIZE = 256; /**< Echo buffer size */
|
||||
static final String ECHO_BEGIN = "PSTART"; /**< Begin pattern of the response */
|
||||
static final String ECHO_END = "PSTOP"; /**< End pattern of the response */
|
||||
|
||||
private Com com_;
|
||||
private Log log_;
|
||||
private Transaction transaction_;
|
||||
private int duration_;
|
||||
private byte[] code_;
|
||||
|
||||
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[] code_; /**< The desired code for the session */
|
||||
|
||||
/**
|
||||
* Basic constructor
|
||||
* @param com The Communication module to use
|
||||
* @param log The logging module to use
|
||||
* @param code The code to use
|
||||
* @param duration The duration to use
|
||||
*/
|
||||
Echo (Com com, Log log, byte[] code, int duration) {
|
||||
com_ = com;
|
||||
log_ = log;
|
||||
duration_ = duration;
|
||||
// Allocate memory for the response
|
||||
transaction_= new Transaction(null, new byte[ECHO_BUFFER_SIZE]);
|
||||
code_ = code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Functionality to drain the response buffer for the welcome message
|
||||
* from the server
|
||||
* @param code The code that we will use (for printing, not sending)
|
||||
*/
|
||||
void caption (byte[] code) {
|
||||
String line;
|
||||
|
||||
@ -31,6 +55,10 @@ class Echo {
|
||||
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;
|
||||
|
||||
@ -1,31 +1,48 @@
|
||||
/**
|
||||
* @file GPS.java
|
||||
*
|
||||
* @author Christos Choutouridis AEM:8997
|
||||
* @email cchoutou@ece.auth.gr
|
||||
*/
|
||||
package net.hoo2.auth.vmodem;
|
||||
|
||||
/** @name imports */
|
||||
/** @{ */
|
||||
import java.util.Arrays;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @class GPS
|
||||
*
|
||||
* Class to used for the GPS session
|
||||
*/
|
||||
class GPS {
|
||||
static final int GPS_BUFFER_SIZE = 256;
|
||||
static final String GPS_BEGIN = "START ITHAKI GPS TRACKING";
|
||||
static final String GPS_END = "STOP ITHAKI GPS TRACKING";
|
||||
static final int GPS_USE_TRACK = 1;
|
||||
static final String GPS_TRACK_PREFIX = "R=";
|
||||
static final String GPS_IMAGE_PREFIX = "T=";
|
||||
static final int GPS_MAX_POINTS = 9;
|
||||
static final int GPS_COORDINATES_SIZE = 6;
|
||||
static final int GPS_BUFFER_SIZE = 256; /**< GPS trace buffer size */
|
||||
static final String GPS_BEGIN = "START ITHAKI GPS TRACKING"; /**< starting pattern */
|
||||
static final String GPS_END = "STOP ITHAKI GPS TRACKING"; /**< ending pattern */
|
||||
static final int GPS_USE_TRACK = 1; /**< Which track to use (given) */
|
||||
static final String GPS_TRACK_PREFIX = "R="; /**< GPS command track request prefix */
|
||||
static final String GPS_IMAGE_PREFIX = "T="; /**< GPS command image request prefix */
|
||||
static final int GPS_MAX_POINTS = 9; /**< Maximum points (given) */
|
||||
static final int GPS_COORDINATES_SIZE = 6; /**< Coordinates size */
|
||||
|
||||
static final int GPS_LATITUDE_BEGIN = 17;
|
||||
static final int GPS_LATITUDE_END = 28;
|
||||
static final int GPS_LONGITUDE_BEGIN= 29;
|
||||
static final int GPS_LONGITUDE_END = 41;
|
||||
static final int GPS_LATITUDE_BEGIN = 17; /**< The latitude sequence string position */
|
||||
static final int GPS_LATITUDE_END = 28; /**< The end of latitude sequence string position */
|
||||
static final int GPS_LONGITUDE_BEGIN= 29; /**< The longitude sequence string position */
|
||||
static final int GPS_LONGITUDE_END = 41; /**< The end of longitude sequence string position */
|
||||
|
||||
private Com com_;
|
||||
private Log log_;
|
||||
private Transaction transaction_;
|
||||
private byte[] code_;
|
||||
private int start_;
|
||||
private int duration_;
|
||||
private int points_;
|
||||
private byte[] coordinates_;
|
||||
|
||||
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 byte[] code_; /**< The desired code for the session */
|
||||
private int start_; /**< Starting point [sec] */
|
||||
private int duration_; /**< Duration of requested trace */
|
||||
private int points_; /**< Number of points to fetch from the above trace */
|
||||
private byte[] coordinates_; /**< Coordinates buffer */
|
||||
|
||||
/**
|
||||
* Basic constructor
|
||||
*/
|
||||
GPS (Com com, Log log, byte[] code, int start, int duration, int points) {
|
||||
com_ = com;
|
||||
log_ = log;
|
||||
@ -37,6 +54,10 @@ class GPS {
|
||||
coordinates_= new byte[GPS_COORDINATES_SIZE];
|
||||
}
|
||||
|
||||
/**
|
||||
* Functionality to drain the response buffer for the welcome message
|
||||
* from the server
|
||||
*/
|
||||
void caption () {
|
||||
String line;
|
||||
|
||||
@ -49,10 +70,15 @@ class GPS {
|
||||
log_.out(line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Main transaction loop. It send requests to server, get the response
|
||||
* and log the procedure while doing it.
|
||||
* @return the image request code to pass to image module
|
||||
*/
|
||||
String run () {
|
||||
String code, image_code;
|
||||
String line;
|
||||
|
||||
|
||||
log_.out("Get traces");
|
||||
image_code = new String(code_);
|
||||
for (int trace =start_ ; trace < start_+duration_ ; trace += duration_/points_) {
|
||||
@ -72,7 +98,15 @@ class GPS {
|
||||
}
|
||||
return image_code;
|
||||
}
|
||||
|
||||
|
||||
/** @name private helper API */
|
||||
/** @{ */
|
||||
|
||||
/**
|
||||
* Extract coordinates from response
|
||||
* @param stream The stream to search
|
||||
* @return The coordinates buffer
|
||||
*/
|
||||
private byte[] _get_coordinates (byte[] stream) {
|
||||
int start = Com.detect(stream, "GPGGA".getBytes(), stream.length);
|
||||
double latitude = _nmea2dec (Double.valueOf(
|
||||
@ -95,10 +129,15 @@ class GPS {
|
||||
- coordinates_[4]/60.0)*3600); // latitude "
|
||||
return coordinates_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A helper to convert the NMEA format to canonical
|
||||
* decimal coordinate format
|
||||
*/
|
||||
double _nmea2dec (double c) {
|
||||
int d = (int)c/100;
|
||||
c -= d*100;
|
||||
return d + (c/60);
|
||||
}
|
||||
/** @} */
|
||||
}
|
||||
|
||||
@ -1,30 +1,59 @@
|
||||
/**
|
||||
* @file Image.java
|
||||
*
|
||||
* @author Christos Choutouridis AEM:8997
|
||||
* @email cchoutou@ece.auth.gr
|
||||
*/
|
||||
package net.hoo2.auth.vmodem;
|
||||
|
||||
/** @name imports */
|
||||
/** @{ */
|
||||
import java.io.*;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @class Image
|
||||
*
|
||||
* Class to used for the error free and non error free image requests
|
||||
*/
|
||||
class Image {
|
||||
static final int IMAGE_BUFFER_SIZE = 256*1024;
|
||||
static final byte[] IMAGE_BEGIN = {(byte)0xFF, (byte)0xD8};
|
||||
static final byte[] IMAGE_END = {(byte)0xFF, (byte)0xD9};
|
||||
static final int IMAGE_BUFFER_SIZE = 256*1024; /**< image buffer size */
|
||||
static final byte[] IMAGE_BEGIN = {(byte)0xFF, (byte)0xD8}; /**< jpeg image begin pattern */
|
||||
static final byte[] IMAGE_END = {(byte)0xFF, (byte)0xD9}; /**< jpeg image end pattern */
|
||||
|
||||
private Com com_;
|
||||
private Log log_;
|
||||
private Transaction transaction_;
|
||||
private String filename_;
|
||||
private int items_;
|
||||
private byte[] code_;
|
||||
|
||||
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 String filename_; /**< The filename to store */
|
||||
private int items_; /**< how many images to fetch */
|
||||
private byte[] code_; /**< The image request code for the virtual lab */
|
||||
|
||||
/**
|
||||
* Basic constructor
|
||||
* @param com The com module to use
|
||||
* @param log The log module to use
|
||||
* @param code The request code
|
||||
* @param filename The filename
|
||||
* @param items How many items to fetch
|
||||
*/
|
||||
Image (Com com, Log log, byte[] code, String filename, int items) {
|
||||
com_ = com;
|
||||
log_ = log;
|
||||
// Allocate memory for the response
|
||||
transaction_= new Transaction(null, new byte[IMAGE_BUFFER_SIZE]);
|
||||
filename_ = filename;
|
||||
items_ = items;
|
||||
code_ = code;
|
||||
}
|
||||
|
||||
|
||||
/** Get function for the code */
|
||||
void code (byte[] code) { code_ = code; }
|
||||
|
||||
/**
|
||||
* Functionality to drain the response buffer for the welcome message
|
||||
* from the server
|
||||
* @param code The code that we will use (for printing, not sending)
|
||||
*/
|
||||
void caption (byte[] code) {
|
||||
String line;
|
||||
|
||||
@ -35,12 +64,17 @@ class Image {
|
||||
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 () {
|
||||
String file, line;
|
||||
BufferedOutputStream ostream;
|
||||
|
||||
for (int i =1 ; i<= items_ ; ++i) {
|
||||
// Make the filename string
|
||||
if (items_>1)
|
||||
file = filename_ + "_" + i + ".jpg";
|
||||
else
|
||||
|
||||
@ -1,19 +1,42 @@
|
||||
/**
|
||||
* @file Log.java
|
||||
*
|
||||
* @author Christos Choutouridis AEM:8997
|
||||
* @email cchoutou@ece.auth.gr
|
||||
*/
|
||||
package net.hoo2.auth.vmodem;
|
||||
|
||||
/** @name imports */
|
||||
/** @{ */
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @class Log
|
||||
*
|
||||
* A common log functionality class for all sessions
|
||||
*/
|
||||
class Log {
|
||||
|
||||
private String logfile_;
|
||||
private boolean verbose_;
|
||||
private PrintWriter writer_;
|
||||
private String logfile_; /**< The log file name */
|
||||
private boolean verbose_; /**< The desired verbosity (for the console)*/
|
||||
private PrintWriter writer_; /**< A buffered writer to use for streaming */
|
||||
|
||||
/**
|
||||
* Basic constructor
|
||||
* @param logfile The log filename
|
||||
* @param verbose The desired verbosity (for the console)
|
||||
*/
|
||||
Log (String logfile, boolean verbose) {
|
||||
logfile_ = logfile;
|
||||
verbose_ = verbose;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Try to open the log file
|
||||
* @return The status of the operation
|
||||
*/
|
||||
boolean open () {
|
||||
if (logfile_ != null) {
|
||||
try {
|
||||
@ -26,11 +49,20 @@ class Log {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Try to open a log file
|
||||
* @param logfile The log file to open
|
||||
* @return The status of the operation
|
||||
*/
|
||||
boolean open (String logfile) {
|
||||
logfile_ = logfile;
|
||||
return open();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Close the opened file
|
||||
* @return The status of the operation
|
||||
*/
|
||||
boolean close () {
|
||||
try {
|
||||
if (writer_ != null)
|
||||
@ -40,17 +72,30 @@ class Log {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Log to file and print to console
|
||||
* @param line The line to log
|
||||
* @param out Console output request flag. If true, echo the line to console
|
||||
*/
|
||||
void write (String line, boolean out) {
|
||||
if (logfile_ != null) writer_.println(line);
|
||||
if (verbose_ || out) System.out.println(line);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Log to file and print to console
|
||||
* @param line The line to log
|
||||
*/
|
||||
void write (String line) {
|
||||
if (logfile_ != null) writer_.println(line);
|
||||
if (verbose_) System.out.println(line);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Echo the line to console
|
||||
* @param line The line to print
|
||||
*/
|
||||
void out (String line) {
|
||||
if (verbose_) System.out.println(line);
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ package net.hoo2.auth.vmodem;
|
||||
|
||||
/** @name imports */
|
||||
/** @{ */
|
||||
import org.apache.commons.cli.*;
|
||||
import org.apache.commons.cli.*; /**< command line utility */
|
||||
/** @} */
|
||||
|
||||
|
||||
@ -19,31 +19,35 @@ import org.apache.commons.cli.*;
|
||||
*
|
||||
* @brief This is the main control class of the program.
|
||||
*
|
||||
* This class includes the main function.Using this class's api
|
||||
* the user can ...
|
||||
* This class includes the main function which read the user input
|
||||
* and create the apropriate object for the requested sequence to
|
||||
* retrieve data.
|
||||
*/
|
||||
public class VirtualModem {
|
||||
|
||||
/** @name Data */
|
||||
/** @{ */
|
||||
CommandLine line;
|
||||
CommandLineParser parser;
|
||||
Options options;
|
||||
HelpFormatter formatter;
|
||||
Com com;
|
||||
Log log;
|
||||
CommandLine line; /**< Command line for the argument list */
|
||||
CommandLineParser parser; /**< Parser for the argument list */
|
||||
Options options; /**< Option configuration container */
|
||||
HelpFormatter formatter; /**< An extra helper for -h */
|
||||
Com com; /**< Reference to basic configuration module */
|
||||
Log log; /**< Reference to basig logging module */
|
||||
/** @} */
|
||||
|
||||
/** @name constructors */
|
||||
/** @{ */
|
||||
/**
|
||||
* @brief The main constructor of the class
|
||||
* We allocate memory for the data needed for the command line
|
||||
*/
|
||||
public VirtualModem () {
|
||||
parser = new DefaultParser();
|
||||
options = new Options();
|
||||
formatter = new HelpFormatter();
|
||||
com = new Com();
|
||||
|
||||
|
||||
Option verb = new Option ("v", "verbose", false, "Be more verbose");
|
||||
// Create argument options and a basic help file
|
||||
// for future use.
|
||||
Option verb = new Option ("v", "verbose", false, "Be more verbose to the console");
|
||||
Option help = new Option ("h", "help", false, "Print this message");
|
||||
Option timeout = Option.builder("t")
|
||||
.longOpt("timeout")
|
||||
@ -60,27 +64,40 @@ public class VirtualModem {
|
||||
Option log = Option.builder("l")
|
||||
.longOpt("log")
|
||||
.hasArg()
|
||||
.desc("Log file name")
|
||||
.desc("Log file name to use")
|
||||
.build();
|
||||
Option echo = Option.builder("e")
|
||||
.longOpt("echo")
|
||||
.numberOfArgs(2)
|
||||
.desc ("Request echo sequence")
|
||||
.desc ("Request echo sequence where <arg> = <1> <2>\n"
|
||||
+ " <1>: The echo requested code from virtual lab\n"
|
||||
+ " <2>: The time duration of the session [sec]")
|
||||
.build();
|
||||
Option aqr = Option.builder("a")
|
||||
.longOpt("aqr")
|
||||
.numberOfArgs(3)
|
||||
.desc ("Request aqr sequence")
|
||||
.desc ("Request aqr sequence where <arg> = <1> <2> <3>\n"
|
||||
+ " <1>: The ACK requested code for virtual lab\n"
|
||||
+ " <2>: The NACK requested code from virtual lab\n"
|
||||
+ " <2>: The time duration for the session [sec]")
|
||||
.build();
|
||||
Option img = Option.builder("g")
|
||||
.longOpt("img")
|
||||
.numberOfArgs(3)
|
||||
.desc("Request an image sequence")
|
||||
.desc("Request an image sequence where <arg> = <1> <2> <3>\n"
|
||||
+ " <1>: The image requested code from virtual lab\n"
|
||||
+ " <2>: The filename to use for storing the image (without .jpg)\n"
|
||||
+ " <3>: The requested images to fetch.")
|
||||
.build();
|
||||
Option gps = Option.builder("p")
|
||||
.longOpt("gps")
|
||||
.numberOfArgs(5)
|
||||
.desc("Request a GPS sequence")
|
||||
.numberOfArgs(5) // G8164 10 800 8 gps_10_800
|
||||
.desc("Request a GPS sequence where <arg> = <1> <2> <3> <4>\n"
|
||||
+ " <1>: The gps requested code from virtual lab\n"
|
||||
+ " <2>: The time from trace to use as starting point [sec]\n"
|
||||
+ " <3>: The time duration for the trace to fetch [sec]\n"
|
||||
+ " <4>: The number of points to fetch from the above trace\n"
|
||||
+ " <5>: The filename to use for storing the image (without .jpg)")
|
||||
.build();
|
||||
options.addOption(verb);
|
||||
options.addOption(help);
|
||||
@ -92,8 +109,15 @@ public class VirtualModem {
|
||||
options.addOption(img);
|
||||
options.addOption(gps);
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/** @name private api */
|
||||
/**@{*/
|
||||
|
||||
/**
|
||||
* parse the command line arguments
|
||||
* @param args the arguments to parse
|
||||
* @return the status of the operation
|
||||
*/
|
||||
private boolean getCmdOptions (String[] args) {
|
||||
try {
|
||||
// parse the command line arguments
|
||||
@ -106,10 +130,19 @@ public class VirtualModem {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Dispatch the correct functionality based on arguments
|
||||
* @return the status of the operation (currently true)
|
||||
*/
|
||||
private boolean commandDispatcher () {
|
||||
boolean verbose = false;
|
||||
|
||||
if (line.hasOption("help")) {
|
||||
formatter.printHelp( "virtualModem", options );
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get log and verbose options first
|
||||
if (line.hasOption("verbose"))
|
||||
verbose = true;
|
||||
@ -129,68 +162,64 @@ public class VirtualModem {
|
||||
}
|
||||
|
||||
// Execution dispatcher
|
||||
do {
|
||||
if (line.hasOption("help")) {
|
||||
formatter.printHelp( "virtualModem", options );
|
||||
break;
|
||||
if (line.hasOption("echo")) {
|
||||
byte[] code = line.getOptionValues("echo")[0].getBytes();
|
||||
Echo e = new Echo(com, log, code,
|
||||
Integer.valueOf(line.getOptionValues("echo")[1]));
|
||||
if (com.open()) {
|
||||
e.caption(code);
|
||||
e.run();
|
||||
com.close();
|
||||
|
||||
}
|
||||
if (line.hasOption("echo")) {
|
||||
byte[] code = line.getOptionValues("echo")[0].getBytes();
|
||||
Echo e = new Echo(com, log, code,
|
||||
Integer.valueOf(line.getOptionValues("echo")[1]));
|
||||
if (com.open()) {
|
||||
e.caption(code);
|
||||
e.run();
|
||||
com.close();
|
||||
|
||||
}
|
||||
}
|
||||
else if (line.hasOption("aqr")) {
|
||||
byte[] ack = line.getOptionValues("aqr")[0].getBytes();
|
||||
byte[] nack = line.getOptionValues("aqr")[1].getBytes();
|
||||
AQR a = new AQR(com, log, ack, nack,
|
||||
Integer.valueOf(line.getOptionValues("aqr")[2]));
|
||||
if (com.open()) {
|
||||
a.caption(ack, nack);
|
||||
a.run();
|
||||
com.close();
|
||||
|
||||
}
|
||||
else if (line.hasOption("aqr")) {
|
||||
byte[] ack = line.getOptionValues("aqr")[0].getBytes();
|
||||
byte[] nack = line.getOptionValues("aqr")[1].getBytes();
|
||||
AQR a = new AQR(com, log, ack, nack,
|
||||
Integer.valueOf(line.getOptionValues("aqr")[2]));
|
||||
if (com.open()) {
|
||||
a.caption(ack, nack);
|
||||
a.run();
|
||||
com.close();
|
||||
|
||||
}
|
||||
}
|
||||
else if (line.hasOption("img")) {
|
||||
byte[] code = line.getOptionValues("img")[0].getBytes();
|
||||
Image im = new Image (com, log, code,
|
||||
line.getOptionValues("img")[1],
|
||||
Integer.valueOf(line.getOptionValues("img")[2]));
|
||||
if (com.open()) {
|
||||
im.caption(code);
|
||||
im.run();
|
||||
com.close();
|
||||
}
|
||||
else if (line.hasOption("img")) {
|
||||
byte[] code = line.getOptionValues("img")[0].getBytes();
|
||||
Image im = new Image (com, log, code,
|
||||
line.getOptionValues("img")[1],
|
||||
Integer.valueOf(line.getOptionValues("img")[2]));
|
||||
if (com.open()) {
|
||||
im.caption(code);
|
||||
im.run();
|
||||
com.close();
|
||||
}
|
||||
}
|
||||
else if (line.hasOption("gps")) {
|
||||
byte[] code = line.getOptionValues("gps")[0].getBytes();
|
||||
GPS g = new GPS (com, log, code,
|
||||
Integer.valueOf(line.getOptionValues("gps")[1]),
|
||||
Integer.valueOf(line.getOptionValues("gps")[2]),
|
||||
Integer.valueOf(line.getOptionValues("gps")[3]));
|
||||
Image im = new Image (com, log, null,
|
||||
line.getOptionValues("gps")[4], 1);
|
||||
if (com.open()) {
|
||||
g.caption();
|
||||
im.code(g.run().getBytes());
|
||||
im.run();
|
||||
com.close();
|
||||
}
|
||||
else if (line.hasOption("gps")) {
|
||||
byte[] code = line.getOptionValues("gps")[0].getBytes();
|
||||
GPS g = new GPS (com, log, code,
|
||||
Integer.valueOf(line.getOptionValues("gps")[1]),
|
||||
Integer.valueOf(line.getOptionValues("gps")[2]),
|
||||
Integer.valueOf(line.getOptionValues("gps")[3]));
|
||||
Image im = new Image (com, log, null,
|
||||
line.getOptionValues("gps")[4], 1);
|
||||
if (com.open()) {
|
||||
g.caption();
|
||||
im.code(g.run().getBytes());
|
||||
im.run();
|
||||
com.close();
|
||||
}
|
||||
}
|
||||
} while (false);
|
||||
}
|
||||
|
||||
log.close();
|
||||
return true;
|
||||
}
|
||||
/**@}*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Main
|
||||
*
|
||||
* @brief Main function
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
// allocate the main object
|
||||
@ -199,9 +228,8 @@ public class VirtualModem {
|
||||
// prepare command line input
|
||||
if (vmodem.getCmdOptions (args) != true)
|
||||
return;
|
||||
// Call the requested functionality
|
||||
if (vmodem.commandDispatcher() != true)
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
載入中…
x
新增問題並參考
Block a user