visualiserInput update as well as refactor of number to bytes conversion

#story[778]
main
hba56 9 years ago
parent bd7fefd67e
commit 949b967abb

@ -7,6 +7,10 @@ import java.nio.ByteBuffer;
import java.util.Arrays; import java.util.Arrays;
import java.util.zip.CRC32; import java.util.zip.CRC32;
import static seng302.Networking.Utils.ByteConverter.intToBytes;
import static seng302.Networking.Utils.ByteConverter.longToBytes;
import static seng302.Networking.Utils.ByteConverter.shortToBytes;
/** /**
* Created by hba56 on 21/04/17. * Created by hba56 on 21/04/17.
*/ */
@ -34,7 +38,7 @@ public class BinaryMesageEncoder {
tempHeaderByteBuffer.put(this.headerSync1); tempHeaderByteBuffer.put(this.headerSync1);
tempHeaderByteBuffer.put(this.headerSync2); tempHeaderByteBuffer.put(this.headerSync2);
tempHeaderByteBuffer.put(this.headerMessageType); tempHeaderByteBuffer.put(this.headerMessageType);
tempHeaderByteBuffer.put(longToSixBytes(this.headerTimeStamp)); tempHeaderByteBuffer.put(longToBytes(this.headerTimeStamp, 6));
tempHeaderByteBuffer.putInt(this.headerSourceID); tempHeaderByteBuffer.putInt(this.headerSourceID);
tempHeaderByteBuffer.put(shortToBytes(this.headerMessageLength)); tempHeaderByteBuffer.put(shortToBytes(this.headerMessageLength));
@ -59,26 +63,6 @@ public class BinaryMesageEncoder {
tempMessageByteBuffer.put(intToBytes((int) crc.getValue())); tempMessageByteBuffer.put(intToBytes((int) crc.getValue()));
this.fullMessage = tempMessageByteBuffer.array(); this.fullMessage = tempMessageByteBuffer.array();
}
private byte[] longToSixBytes(long x) {
ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
buffer.putLong(x);
return Arrays.copyOfRange(buffer.array(), 2, 8);
}
private byte[] shortToBytes(short x) {
ByteBuffer buffer = ByteBuffer.allocate(Short.BYTES);
buffer.putShort(x);
return buffer.array();
}
private byte[] intToBytes(int x) {
ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES);
buffer.putInt(x);
return buffer.array();
} }
public byte[] getFullMessage() { public byte[] getFullMessage() {

@ -56,16 +56,16 @@ public class BinaryMessageDecoder {
crc.update(this.fullMessage); crc.update(this.fullMessage);
//run through the checks //run through the checks
if (this.message.length != ByteConverter.bytesToShort(this.headerMessageLength, ByteOrder.BIG_ENDIAN) ){//&& this.message.length != ByteConverter.bytesToShort(this.headerMessageLength, ByteOrder.BIG_ENDIAN)){ if (this.message.length != ByteConverter.bytesToShort(this.headerMessageLength)){//keep like this - hba65
System.err.println("message length in header does not equal the message length"); System.err.println("message length in header does not equal the message length");
System.err.println("message length in header: " + ByteConverter.bytesToInt(this.headerMessageLength)); System.err.println("message length in header: " + ByteConverter.bytesToInt(this.headerMessageLength));
System.err.println("message length: " + this.message.length); System.err.println("message length: " + this.message.length);
return null; return null;
}else if(this.headerSync1 != 0x47){ }else if(this.headerSync1 != 0x47){
System.err.println("Sync byte 1 is wrong"); System.err.println("Sync byte 1 is wrong: " + this.headerSync1);
return null; return null;
}else if(this.headerSync2 !=(byte) 0x83){ }else if(this.headerSync2 !=(byte) 0x83){
System.err.println("Sync byte 2 is wrong"); System.err.println("Sync byte 2 is wrong: " + this.headerSync2);
return null; return null;
}/*else if(crc.getValue() != 0){ }/*else if(crc.getValue() != 0){
//todo check crc //todo check crc
@ -78,63 +78,63 @@ public class BinaryMessageDecoder {
switch(mType){ switch(mType){
case HEARTBEAT: case HEARTBEAT:
System.out.println("HeartBeat Message!"); // System.out.println("HeartBeat Message!");
data = new Heartbeat(); data = new Heartbeat();
break; break;
case RACESTATUS: case RACESTATUS:
System.out.println("Race Status Message"); // System.out.println("Race Status Message");
RaceStatusDecoder rsdecoder = new RaceStatusDecoder(this.message); RaceStatusDecoder rsdecoder = new RaceStatusDecoder(this.message);
data = new RaceStatus(rsdecoder.getTime(), rsdecoder.getRace(), rsdecoder.getRaceState(), rsdecoder.getStartTime(), rsdecoder.getRaceWindDir(), rsdecoder.getRaceWindSpeed(), rsdecoder.getRaceType(), rsdecoder.getBoats()); data = new RaceStatus(rsdecoder.getTime(), rsdecoder.getRace(), rsdecoder.getRaceState(), rsdecoder.getStartTime(), rsdecoder.getRaceWindDir(), rsdecoder.getRaceWindSpeed(), rsdecoder.getRaceType(), rsdecoder.getBoats());
break; break;
case DISPLAYTEXTMESSAGE: case DISPLAYTEXTMESSAGE:
System.out.println("Display Text Message"); // System.out.println("Display Text Message");
//no decoder for this. //no decoder for this.
break; break;
case XMLMESSAGE: case XMLMESSAGE:
System.out.println("XML Message!"); // System.out.println("XML Message!");
XMLMessageDecoder xmdecoder = new XMLMessageDecoder(this.message); XMLMessageDecoder xmdecoder = new XMLMessageDecoder(this.message);
xmdecoder.decode(); xmdecoder.decode();
data = new XMLMessage(xmdecoder.getAckNumber(), xmdecoder.getTimeStamp(), xmdecoder.getXmlMsgSubType(), xmdecoder.getSequenceNumber(), xmdecoder.getXmlMsgLength(), xmdecoder.getXmlMessageInputSource()); data = new XMLMessage(xmdecoder.getAckNumber(), xmdecoder.getTimeStamp(), xmdecoder.getXmlMsgSubType(), xmdecoder.getSequenceNumber(), xmdecoder.getXmlMsgLength(), xmdecoder.getXmlMessageInputSource());
break; break;
case RACESTARTSTATUS: case RACESTARTSTATUS:
System.out.println("Race Start Status Message"); // System.out.println("Race Start Status Message");
RaceStartStatusDecoder rssDecoder = new RaceStartStatusDecoder(this.message); RaceStartStatusDecoder rssDecoder = new RaceStartStatusDecoder(this.message);
data = new RaceStartStatus(rssDecoder.getTime(), rssDecoder.getAck(), rssDecoder.getStartTime(), rssDecoder.getRaceID(), rssDecoder. getNotification()); data = new RaceStartStatus(rssDecoder.getTime(), rssDecoder.getAck(), rssDecoder.getStartTime(), rssDecoder.getRaceID(), rssDecoder. getNotification());
break; break;
case YACHTEVENTCODE: case YACHTEVENTCODE:
System.out.println("Yacht Action Code!"); // System.out.println("Yacht Action Code!");
//no decoder //no decoder
break; break;
case YACHTACTIONCODE: case YACHTACTIONCODE:
System.out.println("Yacht Action Code!"); // System.out.println("Yacht Action Code!");
//no decoder //no decoder
break; break;
case CHATTERTEXT: case CHATTERTEXT:
System.out.println("Chatter Text Message!"); // System.out.println("Chatter Text Message!");
//no decoder //no decoder
break; break;
case BOATLOCATION: case BOATLOCATION:
System.out.println("Boat Location Message!"); // System.out.println("Boat Location Message!");
BoatLocationDecoder blDecoder = new BoatLocationDecoder(this.message); BoatLocationDecoder blDecoder = new BoatLocationDecoder(this.message);
data = blDecoder.getMessage(); data = blDecoder.getMessage();
break; break;
case MARKROUNDING: case MARKROUNDING:
System.out.println("Mark Rounding Message!"); // System.out.println("Mark Rounding Message!");
MarkRoundingDecoder mrDecoder = new MarkRoundingDecoder(this.message); MarkRoundingDecoder mrDecoder = new MarkRoundingDecoder(this.message);
data = mrDecoder.getMarkRounding(); data = mrDecoder.getMarkRounding();
break; break;
case COURSEWIND: case COURSEWIND:
System.out.println("Couse Wind Message!"); // System.out.println("Couse Wind Message!");
CourseWindDecoder cwDecoder = new CourseWindDecoder(this.message); CourseWindDecoder cwDecoder = new CourseWindDecoder(this.message);
data =new CourseWinds(cwDecoder.getMessageVersionNumber(), cwDecoder.getByteWindID(), cwDecoder.getLoopMessages()); data =new CourseWinds(cwDecoder.getMessageVersionNumber(), cwDecoder.getByteWindID(), cwDecoder.getLoopMessages());
break; break;
case AVGWIND: case AVGWIND:
System.out.println("Average Wind Message!"); // System.out.println("Average Wind Message!");
AverageWindDecoder awDecoder = new AverageWindDecoder(this.message); AverageWindDecoder awDecoder = new AverageWindDecoder(this.message);
data = awDecoder.getAverageWind(); data = awDecoder.getAverageWind();
break; break;
default: default:
System.out.println("Broken Message!"); // System.out.println("Broken Message!");
break; break;
} }
@ -147,7 +147,7 @@ public class BinaryMessageDecoder {
} }
public int getSourceID() { public int getSourceID() {
return ByteConverter.bytesToInt(this.headerSourceID); return ByteConverter.bytesToInt(this.headerSourceID, ByteOrder.BIG_ENDIAN);
} }
public short getMessageLength() { public short getMessageLength() {

@ -10,6 +10,8 @@ import java.nio.charset.Charset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import static seng302.Networking.Utils.ByteConverter.*;
/** /**
* Created by fwy13 on 19/04/17. * Created by fwy13 on 19/04/17.
*/ */
@ -26,14 +28,14 @@ public class RaceVisionByteEncoder {
ByteBuffer raceStatusMessage = ByteBuffer.allocate(24 + 20*boats.size()); ByteBuffer raceStatusMessage = ByteBuffer.allocate(24 + 20*boats.size());
//Version Number 1 bytes //Version Number 1 bytes
byte versionNum = 0b10; //this changes with the pdf. (2) byte versionNum = 0b10; //this changes with the pdf. (2)
byte[] timeBytes = convert(time, 6);//time (6 bytes) byte[] timeBytes = longToBytes(time, 6);//time (6 bytes)
byte[] raceID = ByteBuffer.allocate(4).putInt(race).array();//race identifier incase multiple races are going at once. byte[] raceID = ByteBuffer.allocate(4).putInt(race).array();//race identifier incase multiple races are going at once.
byte[] raceStatus = convert(raceState, 1);//race status 0 - 10 byte[] raceStatus = intToBytes(raceState, 1);//race status 0 - 10
byte[] expectedStart = convert(startTime, 6);//number of milliseconds from Jan 1, 1970 for when the data is valid byte[] expectedStart = longToBytes(startTime, 6);//number of milliseconds from Jan 1, 1970 for when the data is valid
byte[] raceWind = ByteBuffer.allocate(2).putShort(raceWindDir).array();//North = 0x0000 East = 0x4000 South = 0x8000 byte[] raceWind = ByteBuffer.allocate(2).putShort(raceWindDir).array();//North = 0x0000 East = 0x4000 South = 0x8000
byte[] windSpeed = ByteBuffer.allocate(2).putShort(raceWindSpeed).array();//mm/sec byte[] windSpeed = ByteBuffer.allocate(2).putShort(raceWindSpeed).array();//mm/sec
byte[] numBoats = convert(boats.size(), 1); byte[] numBoats = intToBytes(boats.size(), 1);
byte[] bytesRaceType = convert(raceType, 1);//1 match race, 2 fleet race byte[] bytesRaceType = intToBytes(raceType, 1);//1 match race, 2 fleet race
raceStatusMessage.put(versionNum); raceStatusMessage.put(versionNum);
raceStatusMessage.put(timeBytes); raceStatusMessage.put(timeBytes);
@ -47,11 +49,11 @@ public class RaceVisionByteEncoder {
for (int i = 0; i < boats.size(); i++){ for (int i = 0; i < boats.size(); i++){
int sourceID = 0; //TODO use boats source id. int sourceID = 0; //TODO use boats source id.
byte[] legNum = convert(boats.get(i).getCurrentLeg().getLegNumber(), 1); byte[] legNum = intToBytes(boats.get(i).getCurrentLeg().getLegNumber(), 1);
byte[] numPenalties = convert(0, 1); //TODO use boats in race penalties class byte[] numPenalties = intToBytes(0, 1); //TODO use boats in race penalties class
byte[] numPenaltiesServed = convert(0, 1);//TODO use boats in race penalites served. byte[] numPenaltiesServed = intToBytes(0, 1);//TODO use boats in race penalites served.
byte[] estNextMarkTime = convert((long)0, 6);//TODO use boats estimated time to next mark. byte[] estNextMarkTime = longToBytes((long)0, 6);//TODO use boats estimated time to next mark.
byte[] estFinishTime = convert((long) 0, 6);//TODO use boats estimated time to the finish. byte[] estFinishTime = longToBytes((long) 0, 6);//TODO use boats estimated time to the finish.
raceStatusMessage.putInt(sourceID); raceStatusMessage.putInt(sourceID);
raceStatusMessage.put(legNum); raceStatusMessage.put(legNum);
@ -68,7 +70,7 @@ public class RaceVisionByteEncoder {
//ByteBuffer result = ByteBuffer.allocate(4 + numLines * 32); //ByteBuffer result = ByteBuffer.allocate(4 + numLines * 32);
int messageVersionNumber = 0b1;//version number int messageVersionNumber = 0b1;//version number
short ackNum = 0;//no clue what this does just a placeholder for 2 bytes. short ackNum = 0;//no clue what this does just a placeholder for 2 bytes.
byte[] messLines = convert(message.length, 1); byte[] messLines = intToBytes(message.length, 1);
// result.putInt(messageVersionNumber); // result.putInt(messageVersionNumber);
// result.putShort(ackNum); // result.putShort(ackNum);
@ -84,8 +86,8 @@ public class RaceVisionByteEncoder {
messageLen = 30; messageLen = 30;
} }
ByteBuffer mess = ByteBuffer.allocate(2 + messageLen); ByteBuffer mess = ByteBuffer.allocate(2 + messageLen);
mess.put(convert(message[i].getLineNumber(), 1)); mess.put(intToBytes(message[i].getLineNumber(), 1));
mess.put(convert(messageLen, 1)); mess.put(intToBytes(messageLen, 1));
for (int j = 0; j < messageLen; j ++){ for (int j = 0; j < messageLen; j ++){
mess.put(messageAsBytes[j]); mess.put(messageAsBytes[j]);
} }
@ -94,7 +96,7 @@ public class RaceVisionByteEncoder {
} }
ByteBuffer result = ByteBuffer.allocate(size); ByteBuffer result = ByteBuffer.allocate(size);
result.put(convert(messageVersionNumber, 1)); result.put(intToBytes(messageVersionNumber, 1));
result.putShort(ackNum); result.putShort(ackNum);
result.put(messLines); result.put(messLines);
@ -107,14 +109,14 @@ public class RaceVisionByteEncoder {
public byte[] raceStartStatus(long time, short ack, long startTime, int raceID, char notification){ public byte[] raceStartStatus(long time, short ack, long startTime, int raceID, char notification){
int messageVersion = 0b1; int messageVersion = 0b1;
byte[] timestamp = convert(time, 6); byte[] timestamp = longToBytes(time, 6);
byte[] ackNumber = convert(ack, 2); byte[] ackNumber = intToBytes(ack, 2);
byte[] raceStartTime = convert(startTime, 6); byte[] raceStartTime = longToBytes(startTime, 6);
int raceIdentifier = raceID; int raceIdentifier = raceID;
byte[] notificationType = convert(notification, 1); byte[] notificationType = intToBytes(notification, 1);
ByteBuffer result = ByteBuffer.allocate(20); ByteBuffer result = ByteBuffer.allocate(20);
result.put(convert(messageVersion, 1)); result.put(intToBytes(messageVersion, 1));
result.put(timestamp); result.put(timestamp);
result.put(ackNumber); result.put(ackNumber);
result.put(raceStartTime); result.put(raceStartTime);
@ -127,15 +129,15 @@ public class RaceVisionByteEncoder {
public byte[] yachtEventCode(long time, short acknowledgeNumber, int raceID, int destSourceID, int incidentID, public byte[] yachtEventCode(long time, short acknowledgeNumber, int raceID, int destSourceID, int incidentID,
int eventID){ int eventID){
int messageVersion = 0b10; int messageVersion = 0b10;
byte[] encodeTime = convert(time, 6); byte[] encodeTime = longToBytes(time, 6);
short ackNum = acknowledgeNumber; short ackNum = acknowledgeNumber;
int raceUID = raceID;//TODO chekc if this is an into for a 4 char string. int raceUID = raceID;//TODO chekc if this is an into for a 4 char string.
int destSource = destSourceID; int destSource = destSourceID;
int incident = incidentID; int incident = incidentID;
byte[] event = convert(eventID, 1); byte[] event = intToBytes(eventID, 1);
ByteBuffer result = ByteBuffer.allocate(22); ByteBuffer result = ByteBuffer.allocate(22);
result.put(convert(messageVersion, 1)); result.put(intToBytes(messageVersion, 1));
result.put(encodeTime); result.put(encodeTime);
result.putShort(ackNum); result.putShort(ackNum);
result.putInt(raceUID); result.putInt(raceUID);
@ -147,12 +149,12 @@ public class RaceVisionByteEncoder {
public byte[] chatterText(int messageType, String message){ public byte[] chatterText(int messageType, String message){
int messageVersion = 0b1; int messageVersion = 0b1;
byte[] type = convert(messageType, 1); byte[] type = intToBytes(messageType, 1);
byte[] length = convert(message.length(), 1); byte[] text = message.getBytes();
byte[] text = convert(message, length[0]); byte[] length = intToBytes(text.length, 1);
ByteBuffer result = ByteBuffer.allocate(3 + text.length); ByteBuffer result = ByteBuffer.allocate(3 + text.length);
result.put(convert(messageVersion, 1)); result.put(intToBytes(messageVersion, 1));
result.put(type); result.put(type);
result.put(length); result.put(length);
result.put(text); result.put(text);
@ -162,30 +164,30 @@ public class RaceVisionByteEncoder {
public byte[] boatLocation(BoatLocationMessage boatLocationMessage){ public byte[] boatLocation(BoatLocationMessage boatLocationMessage){
int messageVersionNumber = 0b1; int messageVersionNumber = 0b1;
byte[] time = convert(boatLocationMessage.getTime(), 6); byte[] time = longToBytes(boatLocationMessage.getTime(), 6);
byte[] sourceID = convert(boatLocationMessage.getSourceID(), 4); byte[] sourceID = intToBytes(boatLocationMessage.getSourceID(), 4);
byte[] seqNum = convert(boatLocationMessage.getSequenceNumber(), 4); byte[] seqNum = intToBytes(boatLocationMessage.getSequenceNumber(), 4);
byte[] deviceType = convert(boatLocationMessage.getDeviceType(), 1); byte[] deviceType = intToBytes(boatLocationMessage.getDeviceType(), 1);
byte[] latitude = convert(boatLocationMessage.getLatitude(), 4); byte[] latitude = intToBytes(boatLocationMessage.getLatitude(), 4);
byte[] longitude = convert(boatLocationMessage.getLongitude(), 4); byte[] longitude = intToBytes(boatLocationMessage.getLongitude(), 4);
byte[] altitude = convert(boatLocationMessage.getAltitude(), 4); byte[] altitude = intToBytes(boatLocationMessage.getAltitude(), 4);
byte[] heading = convert(boatLocationMessage.getHeading(), 2); byte[] heading = intToBytes(boatLocationMessage.getHeading(), 2);
byte[] pitch = convert(boatLocationMessage.getPitch(), 2); byte[] pitch = intToBytes(boatLocationMessage.getPitch(), 2);
byte[] roll = convert(boatLocationMessage.getRoll(), 2); byte[] roll = intToBytes(boatLocationMessage.getRoll(), 2);
byte[] boatSpeed = convert(boatLocationMessage.getBoatSpeed(), 2); byte[] boatSpeed = intToBytes(boatLocationMessage.getBoatSpeed(), 2);
byte[] cog = convert(boatLocationMessage.getBoatCOG(), 2); byte[] cog = intToBytes(boatLocationMessage.getBoatCOG(), 2);
byte[] sog = convert(boatLocationMessage.getBoatSOG(), 2); byte[] sog = intToBytes(boatLocationMessage.getBoatSOG(), 2);
byte[] apparentWindSpeed = convert(boatLocationMessage.getApparentWindSpeed(), 2); byte[] apparentWindSpeed = intToBytes(boatLocationMessage.getApparentWindSpeed(), 2);
byte[] apparentWindAngle = convert(boatLocationMessage.getApparentWindAngle(), 2); byte[] apparentWindAngle = intToBytes(boatLocationMessage.getApparentWindAngle(), 2);
byte[] trueWindSpeed = convert(boatLocationMessage.getTrueWindSpeed(), 2); byte[] trueWindSpeed = intToBytes(boatLocationMessage.getTrueWindSpeed(), 2);
byte[] trueWindDirection = convert(boatLocationMessage.getTrueWindDirection(), 2); byte[] trueWindDirection = intToBytes(boatLocationMessage.getTrueWindDirection(), 2);
byte[] trueWindAngle = convert(boatLocationMessage.getTrueWindAngle(), 2); byte[] trueWindAngle = intToBytes(boatLocationMessage.getTrueWindAngle(), 2);
byte[] currentDrift = convert(boatLocationMessage.getCurrentDrift(), 2); byte[] currentDrift = intToBytes(boatLocationMessage.getCurrentDrift(), 2);
byte[] currentSet = convert(boatLocationMessage.getCurrentSet(), 2); byte[] currentSet = intToBytes(boatLocationMessage.getCurrentSet(), 2);
byte[] rudderAngle = convert(boatLocationMessage.getRudderAngle(), 2); byte[] rudderAngle = intToBytes(boatLocationMessage.getRudderAngle(), 2);
ByteBuffer result = ByteBuffer.allocate(56); ByteBuffer result = ByteBuffer.allocate(56);
result.put(convert(messageVersionNumber, 1)); result.put(intToBytes(messageVersionNumber, 1));
result.put(time); result.put(time);
result.put(sourceID); result.put(sourceID);
result.put(seqNum); result.put(seqNum);
@ -212,17 +214,17 @@ public class RaceVisionByteEncoder {
public byte[] markRounding(int time, int ackNumber, int raceID, int sourceID, int boatStatus, int roundingSide, int markType, int markID){ public byte[] markRounding(int time, int ackNumber, int raceID, int sourceID, int boatStatus, int roundingSide, int markType, int markID){
int messageVersionNumber = 0b1; int messageVersionNumber = 0b1;
byte[] byteTime = convert(time, 6); byte[] byteTime = longToBytes(time, 6);
byte[] byteAck = convert(ackNumber, 2); byte[] byteAck = intToBytes(ackNumber, 2);
byte[] byteRaceID = convert(raceID, 4); byte[] byteRaceID = intToBytes(raceID, 4);
byte[] byteSourceID = convert(sourceID, 4); byte[] byteSourceID = intToBytes(sourceID, 4);
byte[] byteBoatStatus = convert(boatStatus, 1); byte[] byteBoatStatus = intToBytes(boatStatus, 1);
byte[] byteRoundingSide = convert(roundingSide, 1); byte[] byteRoundingSide = intToBytes(roundingSide, 1);
byte[] byteMarkType = convert(markType, 1); byte[] byteMarkType = intToBytes(markType, 1);
byte[] byteMarkID = convert(markID, 1); byte[] byteMarkID = intToBytes(markID, 1);
ByteBuffer result = ByteBuffer.allocate(21); ByteBuffer result = ByteBuffer.allocate(21);
result.put(convert(messageVersionNumber, 1)); result.put(intToBytes(messageVersionNumber, 1));
result.put(byteTime); result.put(byteTime);
result.put(byteAck); result.put(byteAck);
result.put(byteRaceID); result.put(byteRaceID);
@ -237,38 +239,38 @@ public class RaceVisionByteEncoder {
public byte[] courseWind(byte windID, ArrayList<CourseWind> courseWinds){ public byte[] courseWind(byte windID, ArrayList<CourseWind> courseWinds){
int messageVersionNumber = 0b1; int messageVersionNumber = 0b1;
byte byteWindID = windID; byte byteWindID = windID;
byte[] loopcount = convert(courseWinds.size(), 1); byte[] loopcount = intToBytes(courseWinds.size(), 1);
ByteBuffer result = ByteBuffer.allocate(3 + 20 * courseWinds.size()); ByteBuffer result = ByteBuffer.allocate(3 + 20 * courseWinds.size());
result.put(convert(messageVersionNumber, 1)); result.put(intToBytes(messageVersionNumber, 1));
result.put(byteWindID); result.put(byteWindID);
result.put(loopcount); result.put(loopcount);
for (CourseWind wind: courseWinds){ for (CourseWind wind: courseWinds){
result.put(convert(wind.getID(), 1)); result.put(intToBytes(wind.getID(), 1));
result.put(convert(wind.getTime(), 6)); result.put(longToBytes(wind.getTime(), 6));
result.put(convert(wind.getRaceID(), 4)); result.put(intToBytes(wind.getRaceID(), 4));
result.put(convert(wind.getWindDirection(), 2)); result.put(intToBytes(wind.getWindDirection(), 2));
result.put(convert(wind.getWindSpeed(), 2)); result.put(intToBytes(wind.getWindSpeed(), 2));
result.put(convert(wind.getBestUpwindAngle(), 2)); result.put(intToBytes(wind.getBestUpwindAngle(), 2));
result.put(convert(wind.getBestDownwindAngle(), 2)); result.put(intToBytes(wind.getBestDownwindAngle(), 2));
result.put(convert(wind.getFlags(), 1)); result.put(intToBytes(wind.getFlags(), 1));
} }
return result.array(); return result.array();
} }
public byte[] averageWind(int time, int rawPeriod, int rawSampleSpeed, int period2, int speed2, int period3, int speed3, int period4, int speed4){ public byte[] averageWind(int time, int rawPeriod, int rawSampleSpeed, int period2, int speed2, int period3, int speed3, int period4, int speed4){
int messageVersionNumber = 0b1; int messageVersionNumber = 0b1;
byte[] byteTime = convert(time,6); byte[] byteTime = longToBytes(time,6);
byte[] byteRawPeriod = convert(rawPeriod, 2); byte[] byteRawPeriod = intToBytes(rawPeriod, 2);
byte[] byteRawSpeed = convert(rawSampleSpeed, 2); byte[] byteRawSpeed = intToBytes(rawSampleSpeed, 2);
byte[] bytePeriod2 = convert(period2, 2); byte[] bytePeriod2 = intToBytes(period2, 2);
byte[] byteSpeed2 = convert(speed2, 2); byte[] byteSpeed2 = intToBytes(speed2, 2);
byte[] bytePeriod3 = convert(period3, 2); byte[] bytePeriod3 = intToBytes(period3, 2);
byte[] byteSpeed3 = convert(speed3, 2); byte[] byteSpeed3 = intToBytes(speed3, 2);
byte[] bytePeriod4 = convert(period4, 2); byte[] bytePeriod4 = intToBytes(period4, 2);
byte[] byteSpeed4 = convert(speed4, 2); byte[] byteSpeed4 = intToBytes(speed4, 2);
ByteBuffer result = ByteBuffer.allocate(23); ByteBuffer result = ByteBuffer.allocate(23);
result.put(convert(messageVersionNumber, 1)); result.put(intToBytes(messageVersionNumber, 1));
result.put(byteTime); result.put(byteTime);
result.put(byteRawPeriod); result.put(byteRawPeriod);
result.put(byteRawSpeed); result.put(byteRawSpeed);
@ -281,67 +283,4 @@ public class RaceVisionByteEncoder {
return result.array(); return result.array();
} }
public byte[] convert(String s, int size){
byte[] m = s.getBytes(Charset.forName("UTF-8"));
int length = m.length;
byte[] result;
if (length > 255){
length = 255;
} else if (size < 1){
result = new byte[0];
return result;
}
result = Arrays.copyOfRange(m, 0, length + 1);
return result;
}
public byte[] convert(int n, int size){
byte[] result;
if (size > 4){
result = new byte[4];
return result;
} else if (size < 1){
result = new byte[0];
return result;
}
ByteBuffer byteBuffer = ByteBuffer.allocate(4);
byteBuffer.putInt(n);
byte[] bytes = byteBuffer.array();
result = Arrays.copyOfRange(bytes, 4 - size, 4);
return result;
}
public byte[] convert(long n, int size){
byte[] result;
if (size > 8){
result = new byte[8];
return result;
} else if (size < 1){
result = new byte[0];
return result;
}
ByteBuffer byteBuffer = ByteBuffer.allocate(8);
byteBuffer.putLong(n);
byte[] bytes = byteBuffer.array();
result = Arrays.copyOfRange(bytes, 8 - size, 8);
return result;
}
public byte[] convert(short n, int size){
byte[] result;
if (size > 2){
result = new byte[2];
return result;
} else if (size < 1){
result = new byte[0];
return result;
}
ByteBuffer byteBuffer = ByteBuffer.allocate(2);
byteBuffer.putShort(n);
byte[] bytes = byteBuffer.array();
result = Arrays.copyOfRange(bytes, 2 - size, 2);
return result;
}
} }

@ -4,23 +4,27 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.util.Arrays; import java.util.Arrays;
import static seng302.Networking.Utils.ByteConverter.intToBytes;
import static seng302.Networking.Utils.ByteConverter.longToBytes;
import static seng302.Networking.Utils.ByteConverter.shortToBytes;
/** /**
* Encodes a XML file into a message of AC35 format * Encodes a XML file into a message of AC35 format
*/ */
public class XMLMessageEncoder { public class XMLMessageEncoder {
private byte messageVersionNumber; private byte[] messageVersionNumber;
private short ackNumber; private short ackNumber;
private long timeStamp; private long timeStamp;
private byte xmlMsgSubType; private byte[] xmlMsgSubType;
private short sequenceNumber; private short sequenceNumber;
private short xmlMsgLength; private short xmlMsgLength;
private String xmlMessage; private String xmlMessage;
public XMLMessageEncoder(byte messageVersionNumber, short ackNumber, long timeStamp, byte xmlMsgSubType, short sequenceNumber, short xmlMsgLenght, String xmlMessage) { public XMLMessageEncoder(short ackNumber, long timeStamp, int xmlMsgSubType, short sequenceNumber, short xmlMsgLenght, String xmlMessage) {
this.messageVersionNumber = messageVersionNumber; this.messageVersionNumber = intToBytes(1, 1);
this.ackNumber = ackNumber; this.ackNumber = ackNumber;
this.timeStamp = timeStamp; this.timeStamp = timeStamp;
this.xmlMsgSubType = xmlMsgSubType; this.xmlMsgSubType = intToBytes(xmlMsgSubType, 1);
this.sequenceNumber = sequenceNumber; this.sequenceNumber = sequenceNumber;
this.xmlMsgLength = xmlMsgLenght; this.xmlMsgLength = xmlMsgLenght;
this.xmlMessage = xmlMessage; this.xmlMessage = xmlMessage;
@ -35,24 +39,18 @@ public class XMLMessageEncoder {
ByteBuffer tempOutputByteBuffer = ByteBuffer.allocate(14 + messageBytes.length); ByteBuffer tempOutputByteBuffer = ByteBuffer.allocate(14 + messageBytes.length);
//ackNumber converted to bytes //ackNumber converted to bytes
byte[] ackNumberBytes = new byte[2]; byte[] ackNumberBytes = shortToBytes(ackNumber, 2);
ackNumberBytes[0] = (byte) (ackNumber & 0xff);
ackNumberBytes[1] = (byte) ((ackNumber >> 8) & 0xff);
//sequenceNumber converted to bytes //sequenceNumber converted to bytes
byte[] sequenceNumberBytes = new byte[2]; byte[] sequenceNumberBytes = shortToBytes(sequenceNumber, 2);
sequenceNumberBytes[0] = (byte) (sequenceNumber & 0xff);
sequenceNumberBytes[1] = (byte) ((sequenceNumber >> 8) & 0xff);
//xmlMsgLength converted to bytes //xmlMsgLength converted to bytes
byte[] xmlMsgLengthBytes = new byte[2]; byte[] xmlMsgLengthBytes = shortToBytes(xmlMsgLength, 2);
xmlMsgLengthBytes[0] = (byte) (xmlMsgLength & 0xff);
xmlMsgLengthBytes[1] = (byte) ((xmlMsgLength >> 8) & 0xff);
tempOutputByteBuffer.put(messageVersionNumber); tempOutputByteBuffer.put(messageVersionNumber);
tempOutputByteBuffer.put(ackNumberBytes); tempOutputByteBuffer.put(ackNumberBytes);
tempOutputByteBuffer.put(longToSixBytes(timeStamp)); tempOutputByteBuffer.put(longToBytes(timeStamp, 6));
tempOutputByteBuffer.put(xmlMsgSubType); tempOutputByteBuffer.put(xmlMsgSubType);
tempOutputByteBuffer.put(sequenceNumberBytes); tempOutputByteBuffer.put(sequenceNumberBytes);
tempOutputByteBuffer.put(xmlMsgLengthBytes); tempOutputByteBuffer.put(xmlMsgLengthBytes);
@ -61,17 +59,4 @@ public class XMLMessageEncoder {
return tempOutputByteBuffer.array(); return tempOutputByteBuffer.array();
} }
private byte[] longToSixBytes(long x) {
ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
buffer.putLong(x);
// System.out.println("====encode====");
// for (byte i:buffer.array()
// ) {
// System.out.println(i);
// }
// System.out.println("====encode====");
return Arrays.copyOfRange(buffer.array(), 2, 8);
}
} }

@ -60,7 +60,6 @@ public class MockOutput
//loop that sends //loop that sends
while(true) while(true)
{ {
System.out.println(timeSinceHeartbeat());
//sends a heartbeat every 5 seconds //sends a heartbeat every 5 seconds
if (timeSinceHeartbeat() >= 5.00){ if (timeSinceHeartbeat() >= 5.00){
outToVisualiser.write(heartbeat()); outToVisualiser.write(heartbeat());
@ -104,7 +103,7 @@ public class MockOutput
* @param messageType the kind of xml string, values given in AC35 spec (5 regatta, 6 race, 7 boat) * @param messageType the kind of xml string, values given in AC35 spec (5 regatta, 6 race, 7 boat)
*/ */
public void parseXMLString(String xmlString, int messageType){ public void parseXMLString(String xmlString, int messageType){
XMLMessageEncoder encoder = new XMLMessageEncoder((byte)1, messageNumber, System.currentTimeMillis(), (byte)messageType, xmlSequenceNumber,(short) xmlString.length(), xmlString); XMLMessageEncoder encoder = new XMLMessageEncoder(messageNumber, System.currentTimeMillis(), messageType, xmlSequenceNumber,(short) xmlString.length(), xmlString);
//iterates the sequence numbers //iterates the sequence numbers
xmlSequenceNumber++; xmlSequenceNumber++;
byte[] encodedXML = encoder.encode(); byte[] encodedXML = encoder.encode();

@ -1,55 +1,134 @@
package seng302.Networking; package seng302.Networking;
import seng302.Networking.BinaryMessageDecoder; import seng302.Networking.BinaryMessageDecoder;
import seng302.Networking.MessageDecoders.XMLMessageDecoder; import seng302.Networking.MessageDecoders.*;
import seng302.Networking.Utils.MessageType; import seng302.Networking.Utils.*;
import java.io.*; import java.io.*;
import java.net.*; import java.net.*;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.util.Arrays; import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import static seng302.Networking.Utils.ByteConverter.bytesToInt; import static seng302.Networking.Utils.ByteConverter.bytesToInt;
import static seng302.Networking.Utils.ByteConverter.bytesToShort; import static seng302.Networking.Utils.ByteConverter.bytesToShort;
import static seng302.Networking.Utils.MessageType.*;
/** /**
* TCP server to act as the mock AC35 streaming interface * TCP server to act as the mock AC35 streaming interface
*/ */
public class VisualiserInput public class VisualiserInput
{ {
public static void main(String argv[]) throws Exception //time since last heartbeat
{ private long lastHeartbeatTime;
//socket port 4942 as 4940 is ac35 live port and 4941 is ac35 test port
//socket port 4942 as 4940 is ac35 live port and 4941 is ac35 test port
private ServerSocket visualiserSocket;
private Socket connectionSocket;
int heartbeatSeqNum;
VisualiserInput() throws IOException{
//sockets to connect to
ServerSocket visualiserSocket = new ServerSocket(4942); ServerSocket visualiserSocket = new ServerSocket(4942);
Socket connectionSocket = visualiserSocket.accept(); Socket connectionSocket = visualiserSocket.accept();
while(true) //this is the test data that streams form the AC35 website
{ // Socket connectionSocket = new Socket("livedata.americascup.com",4941);
//start Time
lastHeartbeatTime = System.currentTimeMillis();
//receiver loop that gets the input
boolean receiverLoop = true;
while(receiverLoop) {
//gets the input from the socket
InputStream inFromClient = connectionSocket.getInputStream(); InputStream inFromClient = connectionSocket.getInputStream();
//converts the input into a byte array that can be read by the decoder
byte[] binaryMessage = getBytes(inFromClient); byte[] binaryMessage = getBytes(inFromClient);
//decode the binary message into readable date
BinaryMessageDecoder testDecoder = new BinaryMessageDecoder(binaryMessage); BinaryMessageDecoder testDecoder = new BinaryMessageDecoder(binaryMessage);
testDecoder.decode(); testDecoder.decode();
System.out.println("--header--");
System.out.println(testDecoder.getMessageType());
System.out.println(testDecoder.getTimeStamp());
System.out.println(testDecoder.getSourceID());
System.out.println(testDecoder.getMessageLength());
System.out.println("----");
if (testDecoder.getMessageType() == MessageType.XMLMESSAGE.getValue()){
XMLMessageDecoder xmlMessageDecoder = new XMLMessageDecoder(testDecoder.getMessage());
xmlMessageDecoder.decode();
System.out.println("--message--");
System.out.println(xmlMessageDecoder.getXmlMessageInputSource());
}
if (testDecoder.getMessageType() == MessageType.HEARTBEAT.getValue()){
System.out.println(bytesToInt(testDecoder.getMessage()));
}
//checks which message is being received and does what is needed for that message
MessageType mType = MessageType.valueOf((byte) testDecoder.getMessageType());
switch (mType) {
case HEARTBEAT:
lastHeartbeatTime = System.currentTimeMillis();
//note: if the program runs for over 340 years, this will crash.
heartbeatSeqNum = ByteConverter.bytesToInt(testDecoder.getMessage(), ByteOrder.BIG_ENDIAN);
System.out.println("HeartBeat Message! " + heartbeatSeqNum);
break;
case RACESTATUS:
System.out.println("Race Status Message");
break;
case DISPLAYTEXTMESSAGE:
System.out.println("Display Text Message");
//no decoder for this.
break;
case XMLMESSAGE:
System.out.println("XML Message!");
XMLMessageDecoder xmlMessageDecoder = new XMLMessageDecoder(testDecoder.getMessage());
xmlMessageDecoder.decode();
System.out.println(xmlMessageDecoder.getXmlMessageInputSource());
break;
case RACESTARTSTATUS:
System.out.println("Race Start Status Message");
break;
case YACHTEVENTCODE:
System.out.println("Yacht Action Code!");
//no decoder
break;
case YACHTACTIONCODE:
System.out.println("Yacht Action Code!");
//no decoder
break;
case CHATTERTEXT:
System.out.println("Chatter Text Message!");
//no decoder
break;
case BOATLOCATION:
System.out.println("Boat Location Message!");
break;
case MARKROUNDING:
System.out.println("Mark Rounding Message!");
break;
case COURSEWIND:
System.out.println("Course Wind Message!");
break;
case AVGWIND:
System.out.println("Average Wind Message!");
break;
default:
System.out.println("Broken Message!");
break;
}
//if no heartbeat has been received in more than 6 seconds
//the connection will need to be restarted
if (timeSinceHeartbeat() > 6){
System.out.println("Connection has stopped, trying to reconnect");
receiverLoop = false;
}
} }
} }
/**
* calculates the time since last heartbeat
* @return time since last heartbeat
*/
private double timeSinceHeartbeat() {
long now = System.currentTimeMillis();
return (now - lastHeartbeatTime) / 1000.0;
}
/** /**
* Takes an inputStream and reads the first 15 bytes (the header) and gets the message length * Takes an inputStream and reads the first 15 bytes (the header) and gets the message length
* for the whole message then reads that and returns the byte array * for the whole message then reads that and returns the byte array
@ -61,13 +140,18 @@ public class VisualiserInput
byte[] headerBytes = new byte[15]; byte[] headerBytes = new byte[15];
int i = inStream.read(headerBytes); int i = inStream.read(headerBytes);
byte[] messageLenBytes = Arrays.copyOfRange(headerBytes, 13, 15); byte[] messageLenBytes = Arrays.copyOfRange(headerBytes, 13, 15);
short messageLen = bytesToShort(messageLenBytes, ByteOrder.BIG_ENDIAN); short messageLen = bytesToShort(messageLenBytes);
byte[] messageBytesWithCRC = new byte[messageLen+4]; byte[] messageBytesWithCRC = new byte[messageLen+4];
int j = inStream.read(messageBytesWithCRC); int j = inStream.read(messageBytesWithCRC);
ByteBuffer binaryMessageBytes = ByteBuffer.allocate(i+j); ByteBuffer binaryMessageBytes = ByteBuffer.allocate(headerBytes.length+messageBytesWithCRC.length);
binaryMessageBytes.put(headerBytes); binaryMessageBytes.put(headerBytes);
binaryMessageBytes.put(messageBytesWithCRC); binaryMessageBytes.put(messageBytesWithCRC);
return binaryMessageBytes.array(); return binaryMessageBytes.array();
} }
public static void main(String argv[]) throws Exception
{
VisualiserInput reciever = new VisualiserInput();
}
} }

@ -25,7 +25,7 @@ public class BinaryMessageDecoderTest {
xmlString.append(line.trim()); xmlString.append(line.trim());
} }
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
XMLMessageEncoder testEncoder = new XMLMessageEncoder((byte)1, (short)1, time, (byte)7, (short)1, (short)xmlString.length(), xmlString.toString()); XMLMessageEncoder testEncoder = new XMLMessageEncoder((short)1, time, (byte)7, (short)1, (short)xmlString.length(), xmlString.toString());
byte[] encodedMessage = testEncoder.encode(); byte[] encodedMessage = testEncoder.encode();

@ -25,7 +25,7 @@ public class XMLMessageDecoderTest {
xmlString.append(line.trim()); xmlString.append(line.trim());
} }
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
XMLMessageEncoder testEncoder = new XMLMessageEncoder((byte)1, (short)1, time, (byte)7, (short)1, (short)xmlString.length(), xmlString.toString()); XMLMessageEncoder testEncoder = new XMLMessageEncoder((short)1, time, (byte)7, (short)1, (short)xmlString.length(), xmlString.toString());
byte[] encodedXML = testEncoder.encode(); byte[] encodedXML = testEncoder.encode();

@ -21,7 +21,7 @@ public class XMLMessageEncoderTest {
while((line=br.readLine())!= null){ while((line=br.readLine())!= null){
xmlString.append(line.trim()); xmlString.append(line.trim());
} }
XMLMessageEncoder testEncoder = new XMLMessageEncoder((byte)1, (short)1, System.currentTimeMillis(), (byte)7, (short)1, (short)xmlString.length(), xmlString.toString()); XMLMessageEncoder testEncoder = new XMLMessageEncoder((short)1, System.currentTimeMillis(), (byte)7, (short)1, (short)xmlString.length(), xmlString.toString());
byte[] encodedXML = testEncoder.encode(); byte[] encodedXML = testEncoder.encode();
@ -43,7 +43,7 @@ public class XMLMessageEncoderTest {
while((line=br.readLine())!= null){ while((line=br.readLine())!= null){
xmlString.append(line.trim()); xmlString.append(line.trim());
} }
XMLMessageEncoder testEncoder = new XMLMessageEncoder((byte)1, (short)1, System.currentTimeMillis(), (byte)7, (short)1, (short)1, xmlString.toString()); XMLMessageEncoder testEncoder = new XMLMessageEncoder((short)1, System.currentTimeMillis(), (byte)7, (short)1, (short)1, xmlString.toString());
byte[] encodedXML = testEncoder.encode(); byte[] encodedXML = testEncoder.encode();

Loading…
Cancel
Save