refactored networking code from networkingTest

#story[778, 782]
This commit is contained in:
hba56
2017-04-25 12:38:13 +12:00
parent 67b73ec1db
commit e9578fc63b
48 changed files with 2442 additions and 14 deletions
@@ -0,0 +1,87 @@
package seng302.Networking;
import seng302.Networking.Utils.MessageType;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.zip.CRC32;
/**
* Created by hba56 on 21/04/17.
*/
public class BinaryMesageEncoder {
private byte[] fullMessage;
private byte[] header;
private byte[] message;
//private byte[] crc;
private byte headerSync1 = (byte)0x47;
private byte headerSync2 = (byte)0x83;
private byte headerMessageType;
private long headerTimeStamp;
private int headerSourceID;
private short headerMessageLength;
public BinaryMesageEncoder(MessageType headerMessageType, long headerTimeStamp, int headerSourceID, short headerMessageLength, byte[] message){
//set the header
this.headerMessageType = headerMessageType.getValue();
this.headerTimeStamp = headerTimeStamp;
this.headerSourceID = headerSourceID;
this.headerMessageLength = headerMessageLength;
ByteBuffer tempHeaderByteBuffer = ByteBuffer.allocate(15);
tempHeaderByteBuffer.put(this.headerSync1);
tempHeaderByteBuffer.put(this.headerSync2);
tempHeaderByteBuffer.put(this.headerMessageType);
tempHeaderByteBuffer.put(longToSixBytes(this.headerTimeStamp));
tempHeaderByteBuffer.putInt(this.headerSourceID);
tempHeaderByteBuffer.put(shortToBytes(this.headerMessageLength));
this.header = tempHeaderByteBuffer.array();
//set the message
this.message = message;
//set full message
ByteBuffer tempMessageByteBuffer = ByteBuffer.allocate(19+this.headerMessageLength);
tempMessageByteBuffer.put(this.header);
tempMessageByteBuffer.put(this.message);
CRC32 crc = new CRC32();
crc.reset();
byte[] messageAndHeader = new byte[this.header.length + this.message.length];
System.arraycopy(this.header, 0, messageAndHeader, 0, this.header.length);
System.arraycopy(this.message, 0, messageAndHeader, this.header.length, this.message.length);
crc.update(messageAndHeader);
//System.out.println(Arrays.toString(messageAndHeader));
tempMessageByteBuffer.put(intToBytes((int) crc.getValue()));
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() {
return fullMessage;
}
}
@@ -1,6 +1,6 @@
package seng302.Networking.MessageDecoders;
import seng302.Networking.UtilFiles.BoatLocationMessage;
import seng302.Networking.Utils.BoatLocationMessage;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -1,6 +1,6 @@
package seng302.Networking.MessageDecoders;
import seng302.Networking.UtilFiles.CourseWind;
import seng302.Networking.Utils.CourseWind;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -1,7 +1,10 @@
package seng302.Networking.MessageDecoders;
import seng302.Model.BoatInRace;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
/**
@@ -1,6 +1,6 @@
package seng302.Networking.MessageDecoders;
import seng302.Networking.UtilFiles.BoatStatus;
import seng302.Networking.Utils.BoatStatus;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -0,0 +1,347 @@
package seng302.Networking.MessageEncoders;
import seng302.Model.BoatInRace;
import seng302.Networking.Utils.BoatLocationMessage;
import seng302.Networking.Utils.CourseWind;
import seng302.Networking.Utils.RaceMessage;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
/**
* Created by fwy13 on 19/04/17.
*/
public class RaceVisionByteEncoder {
public byte[] heartBeat(int seq){
ByteBuffer heartBeat = ByteBuffer.allocate(4);
heartBeat.putInt(seq);
byte [] result = heartBeat.array();
return result;
}
public byte[] raceStatus(long time, int race, int raceState, long startTime, short raceWindDir, short raceWindSpeed, int raceType, ArrayList<BoatInRace> boats){
ByteBuffer raceStatusMessage = ByteBuffer.allocate(24 + 20*boats.size());
//Version Number 1 bytes
byte versionNum = 0b10; //this changes with the pdf. (2)
byte[] timeBytes = convert(time, 6);//time (6 bytes)
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[] expectedStart = convert(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[] windSpeed = ByteBuffer.allocate(2).putShort(raceWindSpeed).array();//mm/sec
byte[] numBoats = convert(boats.size(), 1);
byte[] bytesRaceType = convert(raceType, 1);//1 match race, 2 fleet race
raceStatusMessage.put(versionNum);
raceStatusMessage.put(timeBytes);
raceStatusMessage.put(raceID);
raceStatusMessage.put(raceStatus);
raceStatusMessage.put(expectedStart);
raceStatusMessage.put(raceWind);
raceStatusMessage.put(windSpeed);
raceStatusMessage.put(numBoats);
raceStatusMessage.put(bytesRaceType);
for (int i = 0; i < boats.size(); i++){
int sourceID = 0; //TODO use boats source id.
byte[] legNum = convert(boats.get(i).getCurrentLeg().getLegNumber(), 1);
byte[] numPenalties = convert(0, 1); //TODO use boats in race penalties class
byte[] numPenaltiesServed = convert(0, 1);//TODO use boats in race penalites served.
byte[] estNextMarkTime = convert((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.
raceStatusMessage.putInt(sourceID);
raceStatusMessage.put(legNum);
raceStatusMessage.put(numPenalties);
raceStatusMessage.put(numPenaltiesServed);
raceStatusMessage.put(estNextMarkTime);
raceStatusMessage.put(estFinishTime);
}
return raceStatusMessage.array();
}
public byte[] displayTextMessage(RaceMessage[] message){
//ByteBuffer result = ByteBuffer.allocate(4 + numLines * 32);
int messageVersionNumber = 0b1;//version number
short ackNum = 0;//no clue what this does just a placeholder for 2 bytes.
byte[] messLines = convert(message.length, 1);
// result.putInt(messageVersionNumber);
// result.putShort(ackNum);
// result.put(messLines);
ArrayList<byte[]> messages = new ArrayList<byte[]>();
int size = 4;
for (int i = 0; i < message.length; i ++){
int messageLen = message[i].getMessageText().getBytes().length;
byte[] messageAsBytes = message[i].getMessageText().getBytes();
if (messageLen < 30){
messageLen = 30;
}
ByteBuffer mess = ByteBuffer.allocate(2 + messageLen);
mess.put(convert(message[i].getLineNumber(), 1));
mess.put(convert(messageLen, 1));
for (int j = 0; j < messageLen; j ++){
mess.put(messageAsBytes[j]);
}
messages.add(mess.array());
size += 2 + messageLen;
}
ByteBuffer result = ByteBuffer.allocate(size);
result.put(convert(messageVersionNumber, 1));
result.putShort(ackNum);
result.put(messLines);
for(byte[] mess: messages){
result.put(mess);
}
return result.array();
}
public byte[] raceStartStatus(long time, short ack, long startTime, int raceID, char notification){
int messageVersion = 0b1;
byte[] timestamp = convert(time, 6);
byte[] ackNumber = convert(ack, 2);
byte[] raceStartTime = convert(startTime, 6);
int raceIdentifier = raceID;
byte[] notificationType = convert(notification, 1);
ByteBuffer result = ByteBuffer.allocate(20);
result.put(convert(messageVersion, 1));
result.put(timestamp);
result.put(ackNumber);
result.put(raceStartTime);
result.putInt(raceIdentifier);
result.put(notificationType);
return result.array();
}
public byte[] yachtEventCode(long time, short acknowledgeNumber, int raceID, int destSourceID, int incidentID,
int eventID){
int messageVersion = 0b10;
byte[] encodeTime = convert(time, 6);
short ackNum = acknowledgeNumber;
int raceUID = raceID;//TODO chekc if this is an into for a 4 char string.
int destSource = destSourceID;
int incident = incidentID;
byte[] event = convert(eventID, 1);
ByteBuffer result = ByteBuffer.allocate(22);
result.put(convert(messageVersion, 1));
result.put(encodeTime);
result.putShort(ackNum);
result.putInt(raceUID);
result.putInt(destSource);
result.putInt(incident);
result.put(event);
return result.array();
}
public byte[] chatterText(int messageType, String message){
int messageVersion = 0b1;
byte[] type = convert(messageType, 1);
byte[] length = convert(message.length(), 1);
byte[] text = convert(message, length[0]);
ByteBuffer result = ByteBuffer.allocate(3 + text.length);
result.put(convert(messageVersion, 1));
result.put(type);
result.put(length);
result.put(text);
return result.array();
}
public byte[] boatLocation(BoatLocationMessage boatLocationMessage){
int messageVersionNumber = 0b1;
byte[] time = convert(boatLocationMessage.getTime(), 6);
byte[] sourceID = convert(boatLocationMessage.getSourceID(), 4);
byte[] seqNum = convert(boatLocationMessage.getSequenceNumber(), 4);
byte deviceType = boatLocationMessage.getDeviceType();
byte[] latitude = convert(boatLocationMessage.getLatitude(), 4);
byte[] longitude = convert(boatLocationMessage.getLongitude(), 4);
byte[] altitude = convert(boatLocationMessage.getAltitude(), 4);
byte[] heading = convert(boatLocationMessage.getHeading(), 2);
byte[] pitch = convert(boatLocationMessage.getPitch(), 2);
byte[] roll = convert(boatLocationMessage.getRoll(), 2);
byte[] boatSpeed = convert(boatLocationMessage.getBoatSpeed(), 2);
byte[] cog = convert(boatLocationMessage.getBoatCOG(), 2);
byte[] sog = convert(boatLocationMessage.getBoatSOG(), 2);
byte[] apparentWindSpeed = convert(boatLocationMessage.getApparentWindSpeed(), 2);
byte[] apparentWindAngle = convert(boatLocationMessage.getApparentWindAngle(), 2);
byte[] trueWindSpeed = convert(boatLocationMessage.getTrueWindSpeed(), 2);
byte[] trueWindDirection = convert(boatLocationMessage.getTrueWindDirection(), 2);
byte[] trueWindAngle = convert(boatLocationMessage.getTrueWindAngle(), 2);
byte[] currentDrift = convert(boatLocationMessage.getCurrentDrift(), 2);
byte[] currentSet = convert(boatLocationMessage.getCurrentSet(), 2);
byte[] rudderAngle = convert(boatLocationMessage.getRudderAngle(), 2);
ByteBuffer result = ByteBuffer.allocate(56);
result.put(convert(messageVersionNumber, 1));
result.put(time);
result.put(sourceID);
result.put(seqNum);
result.put(deviceType);
result.put(latitude);
result.put(longitude);
result.put(altitude);
result.put(heading);
result.put(pitch);
result.put(roll);
result.put(boatSpeed);
result.put(cog);
result.put(sog);
result.put(apparentWindSpeed);
result.put(apparentWindAngle);
result.put(trueWindSpeed);
result.put(trueWindDirection);
result.put(trueWindAngle);
result.put(currentDrift);
result.put(currentSet);
result.put(rudderAngle);
return result.array();
}
public byte[] markRounding(int time, int ackNumber, int raceID, int sourceID, int boatStatus, int roundingSide, int markType, int markID){
int messageVersionNumber = 0b1;
byte[] byteTime = convert(time, 6);
byte[] byteAck = convert(ackNumber, 2);
byte[] byteRaceID = convert(raceID, 4);
byte[] byteSourceID = convert(sourceID, 4);
byte[] byteBoatStatus = convert(boatStatus, 1);
byte[] byteRoundingSide = convert(roundingSide, 1);
byte[] byteMarkType = convert(markType, 1);
byte[] byteMarkID = convert(markID, 1);
ByteBuffer result = ByteBuffer.allocate(21);
result.put(convert(messageVersionNumber, 1));
result.put(byteTime);
result.put(byteAck);
result.put(byteRaceID);
result.put(byteSourceID);
result.put(byteBoatStatus);
result.put(byteRoundingSide);
result.put(byteMarkType);
result.put(byteMarkID);
return result.array();
}
public byte[] courseWind(byte windID, ArrayList<CourseWind> courseWinds){
int messageVersionNumber = 0b1;
byte byteWindID = windID;
byte[] loopcount = convert(courseWinds.size(), 1);
ByteBuffer result = ByteBuffer.allocate(3 + 20 * courseWinds.size());
result.put(convert(messageVersionNumber, 1));
result.put(byteWindID);
result.put(loopcount);
for (CourseWind wind: courseWinds){
result.put(convert(wind.getID(), 1));
result.put(convert(wind.getTime(), 6));
result.put(convert(wind.getRaceID(), 4));
result.put(convert(wind.getWindDirection(), 2));
result.put(convert(wind.getWindSpeed(), 2));
result.put(convert(wind.getBestUpwindAngle(), 2));
result.put(convert(wind.getBestDownwindAngle(), 2));
result.put(convert(wind.getFlags(), 1));
}
return result.array();
}
public byte[] averageWind(int time, int rawPeriod, int rawSampleSpeed, int period2, int speed2, int period3, int speed3, int period4, int speed4){
int messageVersionNumber = 0b1;
byte[] byteTime = convert(time,6);
byte[] byteRawPeriod = convert(rawPeriod, 2);
byte[] byteRawSpeed = convert(rawSampleSpeed, 2);
byte[] bytePeriod2 = convert(period2, 2);
byte[] byteSpeed2 = convert(speed2, 2);
byte[] bytePeriod3 = convert(period3, 2);
byte[] byteSpeed3 = convert(speed3, 2);
byte[] bytePeriod4 = convert(period4, 2);
byte[] byteSpeed4 = convert(speed4, 2);
ByteBuffer result = ByteBuffer.allocate(23);
result.put(convert(messageVersionNumber, 1));
result.put(byteTime);
result.put(byteRawPeriod);
result.put(byteRawSpeed);
result.put(bytePeriod2);
result.put(byteSpeed2);
result.put(bytePeriod3);
result.put(byteSpeed3);
result.put(bytePeriod4);
result.put(byteSpeed4);
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;
}
}
@@ -0,0 +1,77 @@
package seng302.Networking.MessageEncoders;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
/**
* Encodes a XML file into a message of AC35 format
*/
public class XMLMessageEncoder {
private byte messageVersionNumber;
private short ackNumber;
private long timeStamp;
private byte xmlMsgSubType;
private short sequenceNumber;
private short xmlMsgLength;
private String xmlMessage;
public XMLMessageEncoder(byte messageVersionNumber, short ackNumber, long timeStamp, byte xmlMsgSubType, short sequenceNumber, short xmlMsgLenght, String xmlMessage) {
this.messageVersionNumber = messageVersionNumber;
this.ackNumber = ackNumber;
this.timeStamp = timeStamp;
this.xmlMsgSubType = xmlMsgSubType;
this.sequenceNumber = sequenceNumber;
this.xmlMsgLength = xmlMsgLenght;
this.xmlMessage = xmlMessage;
}
public byte[] encode() {
byte[] messageBytes = xmlMessage.getBytes();
if (messageBytes.length > this.xmlMsgLength) {
//System.err.println("Xml message is to big");
return null;
}
ByteBuffer tempOutputByteBuffer = ByteBuffer.allocate(14 + messageBytes.length);
//ackNumber converted to bytes
byte[] ackNumberBytes = new byte[2];
ackNumberBytes[0] = (byte) (ackNumber & 0xff);
ackNumberBytes[1] = (byte) ((ackNumber >> 8) & 0xff);
//sequenceNumber converted to bytes
byte[] sequenceNumberBytes = new byte[2];
sequenceNumberBytes[0] = (byte) (sequenceNumber & 0xff);
sequenceNumberBytes[1] = (byte) ((sequenceNumber >> 8) & 0xff);
//xmlMsgLength converted to bytes
byte[] xmlMsgLengthBytes = new byte[2];
xmlMsgLengthBytes[0] = (byte) (xmlMsgLength & 0xff);
xmlMsgLengthBytes[1] = (byte) ((xmlMsgLength >> 8) & 0xff);
tempOutputByteBuffer.put(messageVersionNumber);
tempOutputByteBuffer.put(ackNumberBytes);
tempOutputByteBuffer.put(longToSixBytes(timeStamp));
tempOutputByteBuffer.put(xmlMsgSubType);
tempOutputByteBuffer.put(sequenceNumberBytes);
tempOutputByteBuffer.put(xmlMsgLengthBytes);
tempOutputByteBuffer.put(messageBytes);
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);
}
}
@@ -1,4 +1,4 @@
package seng302.Networking.UtilFiles;
package seng302.Networking.Utils;
/**
* Created by f123 on 21-Apr-17.
@@ -1,4 +1,4 @@
package seng302.Networking.UtilFiles;
package seng302.Networking.Utils;
/**
* Created by hba56 on 23/04/17.
@@ -1,4 +1,4 @@
package seng302.Networking.UtilFiles;
package seng302.Networking.Utils;
/**
* Created by fwy13 on 21/04/17.
@@ -1,4 +1,4 @@
package seng302.Networking.UtilFiles;
package seng302.Networking.Utils;
/**
* Created by hba56 on 21/04/17.
@@ -1,4 +1,4 @@
package seng302.Networking.UtilFiles;
package seng302.Networking.Utils;
/**
* Created by fwy13 on 19/04/17.