Added Decoding testing and splitting

- Binary Message Decoder now can determine whether the files are correct or not
- Boat Location Message is now a extension of AC35Data which will be read by the TCPClient
- Boat Status is now an extension of AC35Data which will be read by the TCPClient
- CourseWind is now an extension of AC35Data which will be read by TCPClient
- ValueOf static method added MessageType to assist in determining the packet that was received.
- Race Message is now an extension of AC35Data which will be read by TCPClient
- PacketDumpReader created to read the sample file that was provided.
- AC35Packet has been made to store each Dumped file packet.
- AC35 Data Dump has been added to resources/dataDumps as ac35.bin
#story[782]
main
Fan-Wu Yang 9 years ago
parent d960bc67a2
commit c0bf5b1641

@ -1,8 +1,11 @@
package seng302.Networking; package seng302.Networking;
import seng302.Networking.Utils.MessageType;
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.zip.CRC32;
/** /**
* Created by hba56 on 21/04/17. * Created by hba56 on 21/04/17.
@ -36,24 +39,82 @@ public class BinaryMessageDecoder {
this.headerSourceID = Arrays.copyOfRange(this.header, 9, 13); this.headerSourceID = Arrays.copyOfRange(this.header, 9, 13);
this.headerMessageLength = Arrays.copyOfRange(this.header, 13, 15); this.headerMessageLength = Arrays.copyOfRange(this.header, 13, 15);
if (15 > this.fullMessage.length - 4){
//System.err.println("Message is too short.");
return;
}
//get message //get message
this.message = Arrays.copyOfRange(this.fullMessage, 15, this.fullMessage.length - 4); this.message = Arrays.copyOfRange(this.fullMessage, 15, this.fullMessage.length - 4);
//get crc //get crc
this.crc = Arrays.copyOfRange(this.fullMessage, this.fullMessage.length - 4, fullMessage.length); this.crc = Arrays.copyOfRange(this.fullMessage, this.fullMessage.length - 4, fullMessage.length);
CRC32 crc = new CRC32();
crc.reset();
crc.update(this.fullMessage);
//run through the checks //run through the checks
if (this.message.length != bytesToShort(this.headerMessageLength)){ if (this.message.length != twoByteToInt(this.headerMessageLength)){
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: " + bytesToInt(this.headerMessageLength)); System.err.println("message length in header: " + twoByteToInt(this.headerMessageLength));
System.err.println("message length: " + this.message.length); System.err.println("message length: " + this.message.length);
return;
}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");
return;
}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");
}else if(false){ return;
}/*else if(crc.getValue() != ByteBuffer.wrap(this.crc).getInt()){
//todo check crc //todo check crc
System.err.println("CRC is not " + ByteBuffer.wrap(this.crc).getInt() + " and is instead:" + crc.getValue());
return;
}*/
MessageType mType = MessageType.valueOf(this.headerMessageType);
switch(mType){
case HEARTBEAT:
System.out.println("HeartBeat Message!");
break;
case RACESTARTSTATUS:
System.out.println("Race Status Message");
break;
case DISPLAYTEXTMESSAGE:
System.out.println("Display Text Message");
break;
case XMLMESSAGE:
System.out.println("XML Message!");
break;
case RACESTATUS:
System.out.println("Race Start Status!");
break;
case YACHTEVENTCODE:
System.out.println("Yacht Action Code!");
break;
case CHATTERTEXT:
System.out.println("Chatter Text Message!");
break;
case BOATLOCATION:
System.out.println("Boat Location Message!");
break;
case MARKROUNDING:
System.out.println("Mark Rounding Message!");
break;
case COURSEWIND:
System.out.println("Couse Wind Message!");
break;
case AVGWIND:
System.out.println("Average Wind Message!");
break;
default:
System.out.println("Broken Message!");
break;
} }
} }
@ -69,6 +130,22 @@ public class BinaryMessageDecoder {
return num; return num;
} }
private int twoByteToInt(byte[] bytesInt){/*
ByteBuffer byteBuffer = ByteBuffer.allocate(4);
byteBuffer.order(ByteOrder.BIG_ENDIAN);
byteBuffer.put((byte)0);
byteBuffer.put((byte)0);
byteBuffer.put(bytesInt);
int num = byteBuffer.getInt(0);*/
byte[] bytes = new byte[2];
bytes[1] = bytesInt[0];
bytes[0] = bytesInt[1];
int num = ByteBuffer.wrap(bytes).getShort();
return num;
}
private long bytesToLong(byte[] bytesLong){ private long bytesToLong(byte[] bytesLong){
ByteBuffer byteBuffer = ByteBuffer.allocate(8); ByteBuffer byteBuffer = ByteBuffer.allocate(8);
byteBuffer.order(ByteOrder.BIG_ENDIAN); byteBuffer.order(ByteOrder.BIG_ENDIAN);

@ -0,0 +1,67 @@
package seng302.Networking.PacketDump;
import seng302.Networking.BinaryMesageEncoder;
import seng302.Networking.BinaryMessageDecoder;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
/**
* Created by fwy13 on 25/04/17.
*/
public class AC35DumpReader {
private byte[] dump;
private ArrayList<AC35Packet> packets;
public AC35DumpReader(String url) throws IOException, URISyntaxException {
URL uri = getClass().getClassLoader().getResource(url);
Path path = Paths.get(uri.toURI());
dump = Files.readAllBytes(path);
packets = new ArrayList<>();
System.out.println(dump.length);
readAllPackets();
}
private void readAllPackets(){
int pointer = 0;
while(pointer < dump.length){
byte[] messLen = new byte[2];
messLen[1] = dump[pointer + 13];
messLen[0] = dump[pointer + 14];
int messageLength = ByteBuffer.wrap(messLen).getShort();
//System.out.println(messageLength);
packets.add(new AC35Packet(Arrays.copyOfRange(dump, pointer, pointer + messageLength + 19)));
pointer += 19 + messageLength;
}
for (AC35Packet pack: packets){
BinaryMessageDecoder decoder = new BinaryMessageDecoder(pack.getData());
decoder.decode();
}
}
public static void main(String[] args){
try {
AC35DumpReader ac35DumpReader = new AC35DumpReader("dataDumps/ac35.bin");
} catch (IOException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
}

@ -0,0 +1,17 @@
package seng302.Networking.PacketDump;
/**
* Created by fwy13 on 25/04/17.
*/
public class AC35Packet {
byte[] data;
public AC35Packet(byte[] data){
this.data = data;
}
public byte[] getData() {
return data;
}
}

@ -0,0 +1,15 @@
package seng302.Networking.Utils;
/**
* Created by fwy13 on 25/04/17.
*/
public abstract class AC35Data {
protected MessageType type;
public AC35Data (MessageType type){
this.type = type;
}
}

@ -7,7 +7,7 @@ package seng302.Networking.Utils;
/** /**
* Represents the information in a boat location message (AC streaming spec: 4.9). * Represents the information in a boat location message (AC streaming spec: 4.9).
*/ */
public class BoatLocationMessage public class BoatLocationMessage extends AC35Data
{ {
///Version number of the message - is always 1. ///Version number of the message - is always 1.
private byte messageVersionNumber = 1; private byte messageVersionNumber = 1;
@ -78,8 +78,9 @@ public class BoatLocationMessage
/** /**
* Ctor. * Ctor.
*/ */
public BoatLocationMessage() public BoatLocationMessage(MessageType type)
{ {
super(type);
} }
/** /**
@ -107,8 +108,9 @@ public class BoatLocationMessage
* @param currentSet * @param currentSet
* @param rudderAngle * @param rudderAngle
*/ */
public BoatLocationMessage(byte messageVersionNumber, long time, int sourceID, int sequenceNumber, byte deviceType, int latitude, int longitude, int altitude, int heading, short pitch, short roll, int boatSpeed, int boatCOG, int boatSOG, int apparentWindSpeed, short apparentWindAngle, int trueWindSpeed, short trueWindDirection, short trueWindAngle, int currentDrift, int currentSet, short rudderAngle) public BoatLocationMessage(byte messageVersionNumber, long time, int sourceID, int sequenceNumber, byte deviceType, int latitude, int longitude, int altitude, int heading, short pitch, short roll, int boatSpeed, int boatCOG, int boatSOG, int apparentWindSpeed, short apparentWindAngle, int trueWindSpeed, short trueWindDirection, short trueWindAngle, int currentDrift, int currentSet, short rudderAngle, MessageType type)
{ {
super(type);
this.messageVersionNumber = messageVersionNumber; this.messageVersionNumber = messageVersionNumber;
this.time = time; this.time = time;
this.sourceID = sourceID; this.sourceID = sourceID;

@ -3,7 +3,7 @@ package seng302.Networking.Utils;
/** /**
* Created by hba56 on 23/04/17. * Created by hba56 on 23/04/17.
*/ */
public class BoatStatus { public class BoatStatus extends AC35Data{
private int sourceID; private int sourceID;
private byte boatStatus; private byte boatStatus;
private byte legNumber; private byte legNumber;
@ -12,7 +12,8 @@ public class BoatStatus {
private long estTimeAtNextMark; private long estTimeAtNextMark;
private long estTimeAtFinish; private long estTimeAtFinish;
public BoatStatus(int sourceID, byte boatStatus, byte legNumber, byte numPenaltiesAwarded, byte numPenaltiesServed, long estTimeAtNextMark, long estTimeAtFinish) { public BoatStatus(int sourceID, byte boatStatus, byte legNumber, byte numPenaltiesAwarded, byte numPenaltiesServed, long estTimeAtNextMark, long estTimeAtFinish, MessageType type) {
super(type);
this.sourceID = sourceID; this.sourceID = sourceID;
this.boatStatus = boatStatus; this.boatStatus = boatStatus;
this.legNumber = legNumber; this.legNumber = legNumber;

@ -3,13 +3,14 @@ package seng302.Networking.Utils;
/** /**
* Created by fwy13 on 21/04/17. * Created by fwy13 on 21/04/17.
*/ */
public class CourseWind { public class CourseWind extends AC35Data{
private int ID, raceID, windDirection, windSpeed, bestUpwindAngle, bestDownwindAngle, flags; private int ID, raceID, windDirection, windSpeed, bestUpwindAngle, bestDownwindAngle, flags;
private long time; private long time;
public CourseWind(int ID, long time, int raceID, int windDirection, int windSpeed, int bestUpwindAngle, int bestDownwindAngle, public CourseWind(int ID, long time, int raceID, int windDirection, int windSpeed, int bestUpwindAngle, int bestDownwindAngle,
int flags){ int flags, MessageType type){
super(type);
this.ID = ID; this.ID = ID;
this.time = time; this.time = time;
this.raceID = raceID; this.raceID = raceID;

@ -6,7 +6,7 @@ package seng302.Networking.Utils;
public enum MessageType { public enum MessageType {
HEARTBEAT(1), RACESTATUS(12), DISPLAYTEXTMESSAGE(20), HEARTBEAT(1), RACESTATUS(12), DISPLAYTEXTMESSAGE(20),
XMLMESSAGE(26), RACESTARTSTATUS(27), YACHTEVENTCODE(29), YACHTACTIONCODE(31), XMLMESSAGE(26), RACESTARTSTATUS(27), YACHTEVENTCODE(29), YACHTACTIONCODE(31),
CHATTERTEXT(36), BOATLOCATION(37), MARKROUNDING(38), COURSEWIND(44), AVGWIND(47); CHATTERTEXT(36), BOATLOCATION(37), MARKROUNDING(38), COURSEWIND(44), AVGWIND(47), NOTAMESSAGE(0);
private byte value; private byte value;
@ -15,4 +15,35 @@ public enum MessageType {
public byte getValue() { public byte getValue() {
return value; return value;
} }
public static MessageType valueOf(byte bite){
switch(bite){
case 1:
return HEARTBEAT;
case 12:
return RACESTATUS;
case 20:
return DISPLAYTEXTMESSAGE;
case 26:
return XMLMESSAGE;
case 27:
return RACESTARTSTATUS;
case 29:
return YACHTEVENTCODE;
case 31:
return YACHTACTIONCODE;
case 36:
return CHATTERTEXT;
case 37:
return BOATLOCATION;
case 38:
return MARKROUNDING;
case 44:
return COURSEWIND;
case 47:
return AVGWIND;
default:
return NOTAMESSAGE;
}
}
} }

@ -3,12 +3,13 @@ package seng302.Networking.Utils;
/** /**
* Created by fwy13 on 19/04/17. * Created by fwy13 on 19/04/17.
*/ */
public class RaceMessage { public class RaceMessage extends AC35Data {
private int lineNumber; private int lineNumber;
private String messageText; private String messageText;
public RaceMessage(int lineNumber, String messageText){ public RaceMessage(int lineNumber, String messageText, MessageType type){
super(type);
this.lineNumber = lineNumber; this.lineNumber = lineNumber;
this.messageText = messageText; this.messageText = messageText;
} }

Loading…
Cancel
Save