A first testing version and some data from itahki

This commit is contained in:
Christos Houtouridis
2018-11-29 10:37:28 +02:00
parent e2a6319055
commit d328e84cc2
57 changed files with 10421 additions and 606 deletions
+90
View File
@@ -0,0 +1,90 @@
package net.hoo2.auth.vmodem;
import java.util.*;
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 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;
private Com com_;
private Log log_;
private Transaction transaction_;
private int duration_;
private byte[] ack_;
private byte[] nack_;
AQR (Com com, Log log, byte[] ack, byte[] nack, int duration) {
com_ = com;
log_ = log;
duration_ = duration;
transaction_= new Transaction(null, new byte[AQR_BUFFER_SIZE]);
ack_ = ack;
nack_ = nack;
}
void caption (byte[] ack, byte[] nack) {
String line;
line = "Running AQR 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);
}
void run () {
long start;
long now;
long mark =0, delay =0;
String line;
int bads = 0;
boolean good = true;
boolean prev = true;
start = System.currentTimeMillis();
do {
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;
// delay calculation
if (prev && !good) mark = transaction_.departure;
if (!prev && good) delay = transaction_.arrival - mark;
else delay = 0;
prev = good;
line = new String(transaction_.code) + ": "
+ new String(transaction_.getResponse())
+ " Er: " + bads
+ " Tr= " + (transaction_.arrival - transaction_.departure) + " [msec]";
if (delay != 0) line += " Tt= " + delay + " [msec]";
log_.write(line);
now = System.currentTimeMillis();
} while (now - start < duration_*1000);
}
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;
}
private int _crc (byte[] data) {
int calc =0;
for (int i=0 ; i<data.length ; ++i)
calc ^= data[i];
return calc;
}
}
+73 -33
View File
@@ -1,12 +1,17 @@
package net.hoo2.auth.vmodem;
import java.util.Arrays;
import ithakimodem.*;
class Com {
static final int SPEED_DEFAULT = 9600;
static final int SPEED_DEFAULT = 48000;
static final int TIMEOUT_DEFAULT = 2000;
static final String URL_DEFAULT = "ithaki";
private Modem modem_;
private int speed_;
private int timeout_;
Com () {
modem_ = new Modem();
speed_ = SPEED_DEFAULT;
@@ -14,7 +19,7 @@ class Com {
modem_.setSpeed(speed_);
modem_.setTimeout(timeout_);
}
Com (int speed, int timeout) {
Com (Log log, int speed, int timeout) {
modem_ = new Modem();
speed_ = speed;
timeout_ = timeout;
@@ -24,15 +29,19 @@ class Com {
// get/set
int timeout () { return timeout_; }
void timeout (int t) {
timeout_ = t;
modem_.setTimeout(timeout_);
void timeout (int timeout) {
if (timeout_ != timeout) {
timeout_ = timeout;
modem_.setTimeout(timeout_);
}
}
int speed () { return speed_; }
void speed (int speed) {
speed_ = speed;
modem_.setSpeed(speed_);
if (speed_ != speed) {
speed_ = speed;
modem_.setSpeed(speed_);
}
}
@@ -41,59 +50,84 @@ class Com {
boolean close() { return modem_.close(); }
Transaction request (Transaction data, boolean ask, byte[] delimiter) {
Transaction request (Transaction data, byte[] code, byte[] begin, byte[] end, boolean bin) {
int ch =0;
int i =0;
boolean have_begin = (begin != null) ? false : true;
boolean incoming = false;
_clear (data.response);
if (ask) {
_clear (data.response, 0, data.response.length);
if (code != null) {
data.code = code;
modem_.write(data.code);
modem_.write((int)'\r');
data.departure = System.currentTimeMillis() - (long)((8*(data.code.length+1))*(1000.0/speed_));
data.departure = System.currentTimeMillis();// - (long)((8*(data.code.length+1))*(1000.0/speed_));
}
data.size =0;
do {
if (data.size >= data.response.length) {
data.size =0;
return data;
}
try {
ch = modem_.read();
}
catch (Exception e) {
System.out.println (e.getMessage());
System.err.println (e.getMessage());
data.size =0;
return data;
}
if (i == 0)
data.arrival = System.currentTimeMillis() - (long)(8*(1000.0/speed_));
data.response [i++] = (byte)ch;
} while (!_detect (data.response, "\r\n\n\n".getBytes())
&& !_detect (data.response, "NO CARRIER".getBytes())
&& !_detect (data.response, delimiter)
&& ch != -1);
if (!incoming) {
incoming = true;
data.arrival = System.currentTimeMillis();// - (long)(8*(1000.0/speed_));
}
data.response [data.size++] = (byte)ch;
if (!have_begin && (detect(data.response, begin, data.size) != -1)) {
_clear(data.response, 0, data.size);
data.size = _copy (data.response, begin);
have_begin = true;
}
} while (ch != -1 &&
(!have_begin ||
( (bin || (detect (data.response, "\r\n\n\n".getBytes(), data.size) == -1))
&& (bin || (detect (data.response, "NO CARRIER".getBytes(), data.size) == -1))
&& (detect (data.response, end, data.size) == -1)
)
)
);
return data;
}
private boolean _detect (byte[] response, byte[] pattern) {
static int detect (byte[] data, byte[] pattern, int max) {
if (pattern != null) {
for (int i =0 ; i<response.length - pattern.length ; ++i) {
for (int i =0 ; i<max && i<data.length - pattern.length; ++i) {
boolean detected = true;
for (int j=0 ; j<pattern.length ; ++j) {
if (response[i+j] != pattern[j]) {
if (data[i+j] != pattern[j]) {
detected = false;
break;
}
}
if (detected)
return true;
return i;
}
}
return false;
return -1;
}
private void _clear (byte[] buffer) {
for (int i=0 ; i<buffer.length ; ++i)
private void _clear (byte[] buffer, int begin, int end) {
for (int i=begin ; i<end && i<buffer.length ; ++i)
buffer[i] = 0;
}
private Modem modem_;
private int speed_;
private int timeout_;
private int _copy (byte[] dest, byte[] src) {
if (dest.length >= src.length) {
for (int i=0 ; i<src.length ; ++i)
dest[i] = src[i];
return src.length;
}
return 0;
}
}
@@ -103,11 +137,17 @@ class Transaction {
byte[] response;
long departure;
long arrival;
int size;
Transaction (byte[] code, byte[] response) {
this.code = code;
this.response = response;
departure = arrival = 0;
departure = arrival = 0;
size = 0;
}
byte[] getResponse() {
return Arrays.copyOf(response, size);
}
}
+30 -58
View File
@@ -1,78 +1,50 @@
package net.hoo2.auth.vmodem;
import java.io.IOException;
import java.io.PrintWriter;
class Echo {
static final int ECHO_DURATION_DEFAULT = 60;
static final int ECHO_CODE_SIZE = 5;
static final int ECHO_DURATION_DEFAULT = 240;
static final int ECHO_BUFFER_SIZE = 256;
static final int ECHO_RESPONSE_SIZE = 35;
static final String ECHO_DELIMITER = "PSTOP";
static final String ECHO_BEGIN = "PSTART";
static final String ECHO_END = "PSTOP";
private Com com_;
private Transaction transaction_;
private int duration_;
private String logfile_;
private Com com_;
private Log log_;
private Transaction transaction_;
private int duration_;
private byte[] code_;
Echo (Com com, byte[] code, int duration, String logfile) {
Echo (Com com, Log log, byte[] code, int duration) {
com_ = com;
log_ = log;
duration_ = duration;
transaction_= new Transaction(new byte[ECHO_CODE_SIZE],
new byte[ECHO_BUFFER_SIZE]);
transaction_.code = code.clone();
logfile_ = logfile;
transaction_= new Transaction(null, new byte[ECHO_BUFFER_SIZE]);
code_ = code;
}
void run (boolean verbose) {
boolean init;
void caption (byte[] code) {
String line;
line = "Running ECHO with: " + new String(code);
log_.write(line, true);
transaction_ = com_.request (transaction_, null, null, null, false);
line = new String(transaction_.getResponse());
log_.out(line);
}
void run () {
long start;
long now;
PrintWriter writer = null;
String line;
line = "Running echo with: " + new String(transaction_.code);
System.out.println(line);
if (logfile_ != null) {
try {
writer = new PrintWriter(logfile_);
writer.println(line);
}
catch (IOException exp) {
System.err.println( "Open log file failed: " + exp.getMessage() );
return;
}
}
init = true;
start = System.currentTimeMillis();
do {
if (init == true) {
transaction_ = com_.request (transaction_, false, null);
init = false;
line = new String(transaction_.response);
if (verbose) {
System.out.println(line);
}
}
else {
transaction_ = com_.request(transaction_, true, ECHO_DELIMITER.getBytes());
line = new String(transaction_.code)
+ ": "
+ new String(transaction_.response).substring(0, 35)
+ " Resp.time= "
+ (transaction_.arrival - transaction_.departure)
+ " [msec]";
if (logfile_ != null) writer.println(line);
if (verbose) System.out.println(line);
}
transaction_ = com_.request(transaction_, code_, ECHO_BEGIN.getBytes(), ECHO_END.getBytes(), false);
line = new String(transaction_.code) + ": "
+ new String(transaction_.getResponse())
+ " Tr= " + (transaction_.arrival - transaction_.departure) + " [msec]";
log_.write(line);
now = System.currentTimeMillis();
} while (now - start < duration_*1000);
try {
if (writer != null)
writer.close();
} catch (Exception ex) {/*ignore*/}
}
}
+104
View File
@@ -0,0 +1,104 @@
package net.hoo2.auth.vmodem;
import java.util.Arrays;
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_LATITUDE_BEGIN = 17;
static final int GPS_LATITUDE_END = 28;
static final int GPS_LONGITUDE_BEGIN= 29;
static final int GPS_LONGITUDE_END = 41;
private Com com_;
private Log log_;
private Transaction transaction_;
private byte[] code_;
private int start_;
private int duration_;
private int points_;
private byte[] coordinates_;
GPS (Com com, Log log, byte[] code, int start, int duration, int points) {
com_ = com;
log_ = log;
transaction_= new Transaction(null, new byte[GPS_BUFFER_SIZE]);
code_ = code;
start_ = start;
duration_ = duration;
points_ = (points <= GPS_MAX_POINTS) ? points : GPS_MAX_POINTS;
coordinates_= new byte[GPS_COORDINATES_SIZE];
}
void caption () {
String line;
line = "Running GPS with: " + new String(code_)
+ " time [" + start_ + " - " +(start_+duration_) + ") sec" + " [" + points_ + " points]";
log_.write(line, true);
transaction_ = com_.request (transaction_, null, null, null, false);
line = new String(transaction_.getResponse());
log_.out(line);
}
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_) {
code = new String(code_) + GPS_TRACK_PREFIX + GPS_USE_TRACK + String.format("%04d", trace) + "01";
transaction_ = com_.request(transaction_, code.getBytes(), GPS_BEGIN.getBytes(), GPS_END.getBytes(), false);
line = new String(transaction_.code) + ": "
+ new String(transaction_.getResponse())
+ " Tr= " + (transaction_.arrival - transaction_.departure) + " [msec]";
log_.write(line);
_get_coordinates(transaction_.getResponse());
image_code += GPS_IMAGE_PREFIX +
String.format("%02d%02d%02d%02d%02d%02d", coordinates_[0], coordinates_[1],
coordinates_[2], coordinates_[3],
coordinates_[4], coordinates_[5]);
}
return image_code;
}
private byte[] _get_coordinates (byte[] stream) {
int start = Com.detect(stream, "GPGGA".getBytes(), stream.length);
double latitude = _nmea2dec (Double.valueOf(
new String (Arrays.copyOfRange(stream,
start+GPS_LATITUDE_BEGIN,
start+GPS_LATITUDE_END-2))));
double longitude = _nmea2dec (Double.valueOf(
new String(Arrays.copyOfRange(stream,
start+GPS_LONGITUDE_BEGIN,
start+GPS_LONGITUDE_END-2))));
coordinates_[0] = (byte)(longitude); // longitude deg
coordinates_[1] = (byte)((longitude - coordinates_[0]) * 60.0); // longitude '
coordinates_[2] = (byte)((longitude - coordinates_[0]
- coordinates_[1]/60.0)*3600); // longitude "
coordinates_[3] = (byte)(latitude); // latitude deg
coordinates_[4] = (byte)((latitude - coordinates_[3]) * 60.0); // latitude '
coordinates_[5] = (byte)((latitude - coordinates_[3]
- coordinates_[4]/60.0)*3600); // latitude "
return coordinates_;
}
double _nmea2dec (double c) {
int d = (int)c/100;
c -= d*100;
return d + (c/60);
}
}
+67
View File
@@ -0,0 +1,67 @@
package net.hoo2.auth.vmodem;
import java.io.*;
class Image {
static final int IMAGE_BUFFER_SIZE = 128*1024;
static final byte[] IMAGE_BEGIN = {(byte)0xFF, (byte)0xD8};
static final byte[] IMAGE_END = {(byte)0xFF, (byte)0xD9};
private Com com_;
private Log log_;
private Transaction transaction_;
private String filename_;
private int items_;
private byte[] code_;
Image (Com com, Log log, byte[] code, String filename, int items) {
com_ = com;
log_ = log;
transaction_= new Transaction(null, new byte[IMAGE_BUFFER_SIZE]);
filename_ = filename;
items_ = items;
code_ = code;
}
void code (byte[] code) { code_ = code; }
void caption (byte[] code) {
String line;
line = "Running video decoder with: " + new String(code);
log_.write(line, true);
transaction_ = com_.request (transaction_, null, null, null, false);
line = new String(transaction_.getResponse());
log_.out(line);
}
void run () {
String file, line;
BufferedOutputStream ostream;
for (int i =1 ; i<= items_ ; ++i) {
if (items_>1)
file = filename_ + "_" + i + ".jpg";
else
file = filename_ + ".jpg";
line = new String(code_) + ": ";
log_.write(line);
transaction_ = com_.request(transaction_, code_, IMAGE_BEGIN, IMAGE_END, true);
line = "File= " + file
+ " Tr= " + (transaction_.arrival - transaction_.departure) + " [msec]"
+ " Tt= " + (System.currentTimeMillis() - transaction_.departure) + " [msec]";
log_.write(line);
try {
ostream = new BufferedOutputStream(new FileOutputStream(file));
ostream.write(transaction_.response);
ostream.flush();
ostream.close();
}
catch (Exception exp) {
System.err.println ("Error creating " + file + exp.getMessage());
return;
}
}
}
}
+57
View File
@@ -0,0 +1,57 @@
package net.hoo2.auth.vmodem;
import java.io.IOException;
import java.io.PrintWriter;
class Log {
private String logfile_;
private boolean verbose_;
private PrintWriter writer_;
Log (String logfile, boolean verbose) {
logfile_ = logfile;
verbose_ = verbose;
}
boolean open () {
if (logfile_ != null) {
try {
writer_ = new PrintWriter(logfile_);
}
catch (IOException exp) {
System.err.println( "Open log file failed: " + exp.getMessage() );
return false;
}
}
return true;
}
boolean open (String logfile) {
logfile_ = logfile;
return open();
}
boolean close () {
try {
if (writer_ != null)
writer_.close();
} catch (Exception ex) {
return false;
}
return true;
}
void write (String line, boolean out) {
if (logfile_ != null) writer_.println(line);
if (verbose_ || out) System.out.println(line);
}
void write (String line) {
if (logfile_ != null) writer_.println(line);
if (verbose_) System.out.println(line);
}
void out (String line) {
if (verbose_) System.out.println(line);
}
}
+91 -32
View File
@@ -31,8 +31,7 @@ public class VirtualModem {
Options options;
HelpFormatter formatter;
Com com;
String logfile;
boolean verbose;
Log log;
/** @} */
/** @name constructors */
@@ -42,11 +41,9 @@ public class VirtualModem {
options = new Options();
formatter = new HelpFormatter();
com = new Com();
logfile = null;
verbose = false;
// line is initialized in getCmdOptions()
Option verbose = new Option ("v", "verbose", false, "Be more verbose");
Option verb = new Option ("v", "verbose", false, "Be more verbose");
Option help = new Option ("h", "help", false, "Print this message");
Option timeout = Option.builder("t")
.longOpt("timeout")
@@ -70,13 +67,30 @@ public class VirtualModem {
.numberOfArgs(2)
.desc ("Request echo sequence")
.build();
options.addOption(verbose);
Option aqr = Option.builder("a")
.longOpt("aqr")
.numberOfArgs(3)
.desc ("Request aqr sequence")
.build();
Option img = Option.builder("g")
.longOpt("img")
.numberOfArgs(3)
.desc("Request an image sequence")
.build();
Option gps = Option.builder("p")
.longOpt("gps")
.numberOfArgs(5)
.desc("Request a GPS sequence")
.build();
options.addOption(verb);
options.addOption(help);
options.addOption(timeout);
options.addOption(speed);
options.addOption(log);
options.addOption(echo);
options.addOption(aqr);
options.addOption(img);
options.addOption(gps);
}
/** @} */
@@ -94,39 +108,84 @@ public class VirtualModem {
}
private boolean commandDispatcher () {
// Get boolean options first
if (line.hasOption("verbose")) {
boolean verbose = false;
// Get log and verbose options first
if (line.hasOption("verbose"))
verbose = true;
}
// get options
if (line.hasOption("log"))
log = new Log (line.getOptionValue("log"), verbose);
else
log = new Log (null, verbose);
if (log.open() != true)
return false;
// get other options
if (line.hasOption("timeout")) {
com.timeout(Integer.parseInt(line.getOptionValue("timeout")));
}
if (line.hasOption("speed")) {
com.speed(Integer.parseInt(line.getOptionValue("speed")));
}
if (line.hasOption("log")) {
logfile = line.getOptionValue("log");
}
// Execution dispatcher
if (line.hasOption("help")) {
formatter.printHelp( "virtualModem", options );
return true;
}
if (line.hasOption("echo")) {
Echo e = new Echo(com,
line.getOptionValues("echo")[0].getBytes(),
Integer.valueOf(line.getOptionValues("echo")[1]),
logfile);
if (com.open() == true) {
e.run(verbose);
com.close();
do {
if (line.hasOption("help")) {
formatter.printHelp( "virtualModem", options );
break;
}
}
else {
System.err.println ("Error: Unrecognized option");
return false;
}
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("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();
}
}
} while (false);
log.close();
return true;
}
/**