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;
import seng302.Networking.Utils.MessageType;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.zip.CRC32;
/**
* Created by hba56 on 21/04/17.
@ -36,24 +39,82 @@ public class BinaryMessageDecoder {
this.headerSourceID = Arrays.copyOfRange(this.header, 9, 13);
this.headerMessageLength = Arrays.copyOfRange(this.header, 13, 15);
if (15 > this.fullMessage.length - 4){
//System.err.println("Message is too short.");
return;
}
//get message
this.message = Arrays.copyOfRange(this.fullMessage, 15, this.fullMessage.length - 4);
//get crc
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
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: " + bytesToInt(this.headerMessageLength));
System.err.println("message length in header: " + twoByteToInt(this.headerMessageLength));
System.err.println("message length: " + this.message.length);
return;
}else if(this.headerSync1 != 0x47){
System.err.println("Sync byte 1 is wrong");
return;
}else if(this.headerSync2 !=(byte) 0x83){
System.err.println("Sync byte 2 is wrong");
}else if(false){
return;
}/*else if(crc.getValue() != ByteBuffer.wrap(this.crc).getInt()){
//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;
}
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){
ByteBuffer byteBuffer = ByteBuffer.allocate(8);
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).
*/
public class BoatLocationMessage
public class BoatLocationMessage extends AC35Data
{
///Version number of the message - is always 1.
private byte messageVersionNumber = 1;
@ -78,8 +78,9 @@ public class BoatLocationMessage
/**
* Ctor.
*/
public BoatLocationMessage()
public BoatLocationMessage(MessageType type)
{
super(type);
}
/**
@ -107,8 +108,9 @@ public class BoatLocationMessage
* @param currentSet
* @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.time = time;
this.sourceID = sourceID;

@ -3,7 +3,7 @@ package seng302.Networking.Utils;
/**
* Created by hba56 on 23/04/17.
*/
public class BoatStatus {
public class BoatStatus extends AC35Data{
private int sourceID;
private byte boatStatus;
private byte legNumber;
@ -12,7 +12,8 @@ public class BoatStatus {
private long estTimeAtNextMark;
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.boatStatus = boatStatus;
this.legNumber = legNumber;

@ -3,13 +3,14 @@ package seng302.Networking.Utils;
/**
* 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 long time;
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.time = time;
this.raceID = raceID;

@ -6,7 +6,7 @@ package seng302.Networking.Utils;
public enum MessageType {
HEARTBEAT(1), RACESTATUS(12), DISPLAYTEXTMESSAGE(20),
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;
@ -15,4 +15,35 @@ public enum MessageType {
public byte getValue() {
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.
*/
public class RaceMessage {
public class RaceMessage extends AC35Data {
private int lineNumber;
private String messageText;
public RaceMessage(int lineNumber, String messageText){
public RaceMessage(int lineNumber, String messageText, MessageType type){
super(type);
this.lineNumber = lineNumber;
this.messageText = messageText;
}

Loading…
Cancel
Save