diff --git a/src/main/java/seng302/Networking/BinaryMessageDecoder.java b/src/main/java/seng302/Networking/BinaryMessageDecoder.java index d99bf0b9..544d749c 100644 --- a/src/main/java/seng302/Networking/BinaryMessageDecoder.java +++ b/src/main/java/seng302/Networking/BinaryMessageDecoder.java @@ -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); diff --git a/src/main/java/seng302/Networking/PacketDump/AC35DumpReader.java b/src/main/java/seng302/Networking/PacketDump/AC35DumpReader.java new file mode 100644 index 00000000..6d132836 --- /dev/null +++ b/src/main/java/seng302/Networking/PacketDump/AC35DumpReader.java @@ -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 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(); + } + } +} diff --git a/src/main/java/seng302/Networking/PacketDump/AC35Packet.java b/src/main/java/seng302/Networking/PacketDump/AC35Packet.java new file mode 100644 index 00000000..ea6e1a2c --- /dev/null +++ b/src/main/java/seng302/Networking/PacketDump/AC35Packet.java @@ -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; + } +} diff --git a/src/main/java/seng302/Networking/Utils/AC35Data.java b/src/main/java/seng302/Networking/Utils/AC35Data.java new file mode 100644 index 00000000..89867839 --- /dev/null +++ b/src/main/java/seng302/Networking/Utils/AC35Data.java @@ -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; + } + +} diff --git a/src/main/java/seng302/Networking/Utils/BoatLocationMessage.java b/src/main/java/seng302/Networking/Utils/BoatLocationMessage.java index 0fd59c79..9380a0aa 100644 --- a/src/main/java/seng302/Networking/Utils/BoatLocationMessage.java +++ b/src/main/java/seng302/Networking/Utils/BoatLocationMessage.java @@ -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; diff --git a/src/main/java/seng302/Networking/Utils/BoatStatus.java b/src/main/java/seng302/Networking/Utils/BoatStatus.java index 9de6ef39..e0b6d75f 100644 --- a/src/main/java/seng302/Networking/Utils/BoatStatus.java +++ b/src/main/java/seng302/Networking/Utils/BoatStatus.java @@ -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; diff --git a/src/main/java/seng302/Networking/Utils/CourseWind.java b/src/main/java/seng302/Networking/Utils/CourseWind.java index 142c7c11..a077fb87 100644 --- a/src/main/java/seng302/Networking/Utils/CourseWind.java +++ b/src/main/java/seng302/Networking/Utils/CourseWind.java @@ -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; diff --git a/src/main/java/seng302/Networking/Utils/MessageType.java b/src/main/java/seng302/Networking/Utils/MessageType.java index fcdff527..f5aa088c 100644 --- a/src/main/java/seng302/Networking/Utils/MessageType.java +++ b/src/main/java/seng302/Networking/Utils/MessageType.java @@ -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; + } + } } diff --git a/src/main/java/seng302/Networking/Utils/RaceMessage.java b/src/main/java/seng302/Networking/Utils/RaceMessage.java index 1a705574..8df056d3 100644 --- a/src/main/java/seng302/Networking/Utils/RaceMessage.java +++ b/src/main/java/seng302/Networking/Utils/RaceMessage.java @@ -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; } diff --git a/src/main/resources/dataDumps/ac35.bin b/src/main/resources/dataDumps/ac35.bin new file mode 100644 index 00000000..2889c3c2 Binary files /dev/null and b/src/main/resources/dataDumps/ac35.bin differ