You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

166 lines
6.3 KiB

package seng302.Networking;
import seng302.Networking.MessageDecoders.*;
import seng302.Networking.Utils.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.zip.CRC32;
/**
* Created by hba56 on 21/04/17.
*/
public class BinaryMessageDecoder {
private byte[] fullMessage;
private byte[] header;
private byte[] message;
private byte[] crc;
private byte headerSync1;
private byte headerSync2;
private byte headerMessageType;
private byte[] headerTimeStamp;
private byte[] headerSourceID;
private byte[] headerMessageLength;
public BinaryMessageDecoder(byte[] fullMessage) {
this.fullMessage = fullMessage;
}
public AC35Data decode() throws IndexOutOfBoundsException{
//get the header
this.header = Arrays.copyOfRange(this.fullMessage, 0, 15);
this.headerSync1 = this.header[0];
this.headerSync2 = this.header[1];
this.headerMessageType = this.header[2];
this.headerTimeStamp = Arrays.copyOfRange(this.header, 3, 9);
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 null;
}
//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 != 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: " + ByteConverter.bytesToInt(this.headerMessageLength));
System.err.println("message length: " + this.message.length);
return null;
}else if(this.headerSync1 != 0x47){
System.err.println("Sync byte 1 is wrong: " + this.headerSync1);
return null;
}else if(this.headerSync2 !=(byte) 0x83){
System.err.println("Sync byte 2 is wrong: " + this.headerSync2);
return null;
}/*else if(crc.getValue() != 0){
//todo check crc
System.err.println("CRC is not 0 and is instead:" + crc.getValue());
return;
}*/
MessageType mType = MessageType.valueOf(this.headerMessageType);
AC35Data data = null;
switch(mType){
case HEARTBEAT:
// System.out.println("HeartBeat Message!");
data = new Heartbeat();
break;
case RACESTATUS:
// System.out.println("Race Status 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());
break;
case DISPLAYTEXTMESSAGE:
// System.out.println("Display Text Message");
//no decoder for this.
break;
case XMLMESSAGE:
// System.out.println("XML Message!");
XMLMessageDecoder xmdecoder = new XMLMessageDecoder(this.message);
xmdecoder.decode();
data = new XMLMessage(xmdecoder.getAckNumber(), xmdecoder.getTimeStamp(), xmdecoder.getXmlMsgSubType(), xmdecoder.getSequenceNumber(), xmdecoder.getXmlMsgLength(), xmdecoder.getXmlMessageInputSource());
break;
case RACESTARTSTATUS:
// System.out.println("Race Start Status Message");
RaceStartStatusDecoder rssDecoder = new RaceStartStatusDecoder(this.message);
data = new RaceStartStatus(rssDecoder.getTime(), rssDecoder.getAck(), rssDecoder.getStartTime(), rssDecoder.getRaceID(), rssDecoder. getNotification());
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!");
BoatLocationDecoder blDecoder = new BoatLocationDecoder(this.message);
data = blDecoder.getMessage();
break;
case MARKROUNDING:
// System.out.println("Mark Rounding Message!");
MarkRoundingDecoder mrDecoder = new MarkRoundingDecoder(this.message);
data = mrDecoder.getMarkRounding();
break;
case COURSEWIND:
// System.out.println("Couse Wind Message!");
CourseWindDecoder cwDecoder = new CourseWindDecoder(this.message);
data =new CourseWinds(cwDecoder.getMessageVersionNumber(), cwDecoder.getByteWindID(), cwDecoder.getLoopMessages());
break;
case AVGWIND:
// System.out.println("Average Wind Message!");
AverageWindDecoder awDecoder = new AverageWindDecoder(this.message);
data = awDecoder.getAverageWind();
break;
default:
// System.out.println("Broken Message!");
break;
}
return data;
}
public long getTimeStamp() {
return ByteConverter.bytesToLong(this.headerTimeStamp);
}
public int getSourceID() {
return ByteConverter.bytesToInt(this.headerSourceID, ByteOrder.BIG_ENDIAN);
}
public short getMessageLength() {
return ByteConverter.bytesToShort(this.headerMessageLength);
}
public int getMessageType(){
return (int) this.headerMessageType;
}
public byte[] getMessage() {
return message;
}
}