|
|
|
@ -17,42 +17,71 @@ import java.util.zip.CRC32;
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public class BinaryMessageDecoder {
|
|
|
|
public class BinaryMessageDecoder {
|
|
|
|
|
|
|
|
|
|
|
|
///Length of the header.
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Length of the header.
|
|
|
|
|
|
|
|
*/
|
|
|
|
private static final int headerLength = 15;
|
|
|
|
private static final int headerLength = 15;
|
|
|
|
///Length of the CRC.
|
|
|
|
/**
|
|
|
|
private static final int CRCLength = 4;//TODO these should probably be static defined somewhere else to be shared.
|
|
|
|
* Length of the CRC.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
private static final int CRCLength = 4;
|
|
|
|
|
|
|
|
|
|
|
|
///The value the first sync byte should have.
|
|
|
|
/**
|
|
|
|
|
|
|
|
* The value the first sync byte should have.
|
|
|
|
|
|
|
|
*/
|
|
|
|
private static final byte syncByte1 = (byte) 0x47;
|
|
|
|
private static final byte syncByte1 = (byte) 0x47;
|
|
|
|
//The value the second sync byte should have.
|
|
|
|
/**
|
|
|
|
|
|
|
|
* The value the second sync byte should have.
|
|
|
|
|
|
|
|
*/
|
|
|
|
private static final byte syncByte2 = (byte) 0x83;
|
|
|
|
private static final byte syncByte2 = (byte) 0x83;
|
|
|
|
|
|
|
|
|
|
|
|
///The full message.
|
|
|
|
/**
|
|
|
|
|
|
|
|
* The full message.
|
|
|
|
|
|
|
|
*/
|
|
|
|
private byte[] fullMessage;
|
|
|
|
private byte[] fullMessage;
|
|
|
|
///The messageHeader.
|
|
|
|
/**
|
|
|
|
|
|
|
|
* The messageHeader.
|
|
|
|
|
|
|
|
*/
|
|
|
|
private byte[] messageHeader;
|
|
|
|
private byte[] messageHeader;
|
|
|
|
///The messageBody.
|
|
|
|
/**
|
|
|
|
|
|
|
|
* The messageBody.
|
|
|
|
|
|
|
|
*/
|
|
|
|
private byte[] messageBody;
|
|
|
|
private byte[] messageBody;
|
|
|
|
|
|
|
|
|
|
|
|
///The sync bytes from the header..
|
|
|
|
/**
|
|
|
|
|
|
|
|
* The sync bytes from the header.
|
|
|
|
|
|
|
|
*/
|
|
|
|
private byte headerSync1;
|
|
|
|
private byte headerSync1;
|
|
|
|
private byte headerSync2;
|
|
|
|
private byte headerSync2;
|
|
|
|
|
|
|
|
|
|
|
|
///The message type from the header.
|
|
|
|
/**
|
|
|
|
|
|
|
|
* The message type from the header.
|
|
|
|
|
|
|
|
*/
|
|
|
|
private byte headerMessageType;
|
|
|
|
private byte headerMessageType;
|
|
|
|
|
|
|
|
|
|
|
|
///The timestamp from the header.
|
|
|
|
/**
|
|
|
|
|
|
|
|
* The timestamp from the header.
|
|
|
|
|
|
|
|
*/
|
|
|
|
private long headerTimeStamp;
|
|
|
|
private long headerTimeStamp;
|
|
|
|
|
|
|
|
|
|
|
|
///The source ID from the header.
|
|
|
|
/**
|
|
|
|
|
|
|
|
* The source ID from the header.
|
|
|
|
|
|
|
|
*/
|
|
|
|
private int headerSourceID;
|
|
|
|
private int headerSourceID;
|
|
|
|
|
|
|
|
|
|
|
|
///The message body length from the header.
|
|
|
|
/**
|
|
|
|
|
|
|
|
* The message body length from the header.
|
|
|
|
|
|
|
|
*/
|
|
|
|
private int messageBodyLength;
|
|
|
|
private int messageBodyLength;
|
|
|
|
|
|
|
|
|
|
|
|
///CRC value read from message header.
|
|
|
|
/**
|
|
|
|
|
|
|
|
* CRC value read from message header.
|
|
|
|
|
|
|
|
*/
|
|
|
|
private long messageCRCValue;
|
|
|
|
private long messageCRCValue;
|
|
|
|
///Calculated CRC value from message.
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Calculated CRC value from message.
|
|
|
|
|
|
|
|
*/
|
|
|
|
private long calculatedCRCValue;
|
|
|
|
private long calculatedCRCValue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -129,90 +158,20 @@ public class BinaryMessageDecoder {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//Now we create the message object based on what is actually in the message body.
|
|
|
|
//Now we create the message object based on what is actually in the message body.
|
|
|
|
MessageType mType = MessageType.fromByte(headerMessageType);
|
|
|
|
MessageType messageType = MessageType.fromByte(headerMessageType);
|
|
|
|
|
|
|
|
|
|
|
|
/*MessageDecoder decoder = null;
|
|
|
|
MessageDecoder decoder = null;
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
decoder = DecoderFactory.create(mType);
|
|
|
|
decoder = DecoderFactory.create(messageType);
|
|
|
|
|
|
|
|
|
|
|
|
} catch (InvalidMessageTypeException e) {
|
|
|
|
} catch (InvalidMessageTypeException e) {
|
|
|
|
throw new InvalidMessageException("Could not create decoder for MessageType: " + mType, e);
|
|
|
|
throw new InvalidMessageException("Could not create decoder for MessageType: " + messageType, e);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return decoder.decode(messageBody);*/
|
|
|
|
return decoder.decode(messageBody);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch(mType) {
|
|
|
|
|
|
|
|
case HEARTBEAT:
|
|
|
|
|
|
|
|
//System.out.println("Decoding HeartBeat Message!");
|
|
|
|
|
|
|
|
HeartBeatDecoder heartBeatDecoder = new HeartBeatDecoder();
|
|
|
|
|
|
|
|
return heartBeatDecoder.decode(messageBody);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case RACESTATUS:
|
|
|
|
|
|
|
|
//System.out.println("Race Status Message");
|
|
|
|
|
|
|
|
RaceStatusDecoder rsdecoder = new RaceStatusDecoder();
|
|
|
|
|
|
|
|
return rsdecoder.decode(messageBody);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case DISPLAYTEXTMESSAGE:
|
|
|
|
|
|
|
|
//System.out.println("Display Text Message");
|
|
|
|
|
|
|
|
//No decoder for this.
|
|
|
|
|
|
|
|
//throw new InvalidMessageException("Cannot decode DISPLAYTEXTMESSAGE - no decoder.");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case XMLMESSAGE:
|
|
|
|
|
|
|
|
//System.out.println("XML Message!");
|
|
|
|
|
|
|
|
XMLMessageDecoder xmdecoder = new XMLMessageDecoder();
|
|
|
|
|
|
|
|
return xmdecoder.decode(messageBody);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case RACESTARTSTATUS:
|
|
|
|
|
|
|
|
//System.out.println("Race Start Status Message");
|
|
|
|
|
|
|
|
RaceStartStatusDecoder rssDecoder = new RaceStartStatusDecoder();
|
|
|
|
|
|
|
|
return rssDecoder.decode(messageBody);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case YACHTEVENTCODE:
|
|
|
|
|
|
|
|
//System.out.println("Yacht Action Code!");
|
|
|
|
|
|
|
|
//No decoder for this.
|
|
|
|
|
|
|
|
//throw new InvalidMessageException("Cannot decode YACHTEVENTCODE - no decoder.");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case YACHTACTIONCODE:
|
|
|
|
|
|
|
|
//System.out.println("Yacht Action Code!");
|
|
|
|
|
|
|
|
//No decoder for this.
|
|
|
|
|
|
|
|
//throw new InvalidMessageException("Cannot decode YACHTACTIONCODE - no decoder.");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case CHATTERTEXT:
|
|
|
|
|
|
|
|
//System.out.println("Chatter Text Message!");
|
|
|
|
|
|
|
|
//No decoder for this.
|
|
|
|
|
|
|
|
//throw new InvalidMessageException("Cannot decode CHATTERTEXT - no decoder.");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case BOATLOCATION:
|
|
|
|
|
|
|
|
//System.out.println("Boat Location Message!");
|
|
|
|
|
|
|
|
BoatLocationDecoder blDecoder = new BoatLocationDecoder();
|
|
|
|
|
|
|
|
return blDecoder.decode(messageBody);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case MARKROUNDING:
|
|
|
|
|
|
|
|
//System.out.println("Mark Rounding Message!");
|
|
|
|
|
|
|
|
MarkRoundingDecoder mrDecoder = new MarkRoundingDecoder();
|
|
|
|
|
|
|
|
return mrDecoder.decode(messageBody);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case COURSEWIND:
|
|
|
|
|
|
|
|
//System.out.println("Course Wind Message!");
|
|
|
|
|
|
|
|
CourseWindsDecoder cwDecoder = new CourseWindsDecoder();
|
|
|
|
|
|
|
|
return cwDecoder.decode(messageBody);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case AVGWIND:
|
|
|
|
|
|
|
|
//System.out.println("Average Wind Message!");
|
|
|
|
|
|
|
|
AverageWindDecoder awDecoder = new AverageWindDecoder();
|
|
|
|
|
|
|
|
return awDecoder.decode(messageBody);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case BOATACTION:
|
|
|
|
|
|
|
|
BoatActionDecoder baDecoder = new BoatActionDecoder();
|
|
|
|
|
|
|
|
return baDecoder.decode(messageBody);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
//System.out.println("Broken Message!");
|
|
|
|
|
|
|
|
//throw new InvalidMessageException("Broken message! Did not recognise message type: " + headerMessageType + ".");
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
|