Added BoatLocationEncoder.
Updated BoatLocationDecoder test to use new encoder. Updated MockOutput to use new encoder. It logs a warning if encoding fails. #story[1095]
This commit is contained in:
@@ -3,6 +3,7 @@ package mock.app;
|
|||||||
|
|
||||||
|
|
||||||
import network.BinaryMessageEncoder;
|
import network.BinaryMessageEncoder;
|
||||||
|
import network.Exceptions.InvalidMessageException;
|
||||||
import network.MessageEncoders.RaceVisionByteEncoder;
|
import network.MessageEncoders.RaceVisionByteEncoder;
|
||||||
import network.Messages.*;
|
import network.Messages.*;
|
||||||
import network.Messages.Enums.MessageType;
|
import network.Messages.Enums.MessageType;
|
||||||
@@ -13,6 +14,8 @@ import java.io.IOException;
|
|||||||
import java.net.ServerSocket;
|
import java.net.ServerSocket;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TCP server to send race information to connected clients.
|
* TCP server to send race information to connected clients.
|
||||||
@@ -158,12 +161,13 @@ public class MockOutput implements Runnable
|
|||||||
* Encodes/serialises a BoatLocation message, and returns it.
|
* Encodes/serialises a BoatLocation message, and returns it.
|
||||||
* @param boatLocation The BoatLocation message to serialise.
|
* @param boatLocation The BoatLocation message to serialise.
|
||||||
* @return The BoatLocation message in a serialised form.
|
* @return The BoatLocation message in a serialised form.
|
||||||
|
* @throws InvalidMessageException If the message cannot be encoded.
|
||||||
*/
|
*/
|
||||||
private synchronized byte[] parseBoatLocation(BoatLocation boatLocation){
|
private synchronized byte[] parseBoatLocation(BoatLocation boatLocation) throws InvalidMessageException {
|
||||||
|
|
||||||
|
|
||||||
//Encodes the message.
|
//Encodes the message.
|
||||||
byte[] encodedBoatLoc = RaceVisionByteEncoder.boatLocation(boatLocation);
|
byte[] encodedBoatLoc = RaceVisionByteEncoder.encode(boatLocation);
|
||||||
|
|
||||||
//Encodes the full message with header.
|
//Encodes the full message with header.
|
||||||
BinaryMessageEncoder binaryMessageEncoder = new BinaryMessageEncoder(
|
BinaryMessageEncoder binaryMessageEncoder = new BinaryMessageEncoder(
|
||||||
@@ -277,11 +281,19 @@ public class MockOutput implements Runnable
|
|||||||
BoatLocation boatLocation = this.latestMessages.getBoatLocation(sourceID);
|
BoatLocation boatLocation = this.latestMessages.getBoatLocation(sourceID);
|
||||||
if (boatLocation != null) {
|
if (boatLocation != null) {
|
||||||
|
|
||||||
//Encode.
|
|
||||||
byte[] boatLocationBlob = this.parseBoatLocation(boatLocation);
|
|
||||||
|
|
||||||
//Write it.
|
try {
|
||||||
this.outToVisualiser.write(boatLocationBlob);
|
//Encode.
|
||||||
|
byte[] boatLocationBlob = this.parseBoatLocation(boatLocation);
|
||||||
|
|
||||||
|
//Write it.
|
||||||
|
this.outToVisualiser.write(boatLocationBlob);
|
||||||
|
|
||||||
|
} catch (InvalidMessageException e) {
|
||||||
|
Logger.getGlobal().log(Level.WARNING, "Could not encode BoatLocation: " + boatLocation, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
package network.MessageEncoders;
|
||||||
|
|
||||||
|
|
||||||
|
import network.Messages.AC35Data;
|
||||||
|
import network.Messages.BoatLocation;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import static network.Utils.ByteConverter.intToBytes;
|
||||||
|
import static network.Utils.ByteConverter.longToBytes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This encoder can encode a {@link BoatLocation} message.
|
||||||
|
*/
|
||||||
|
public class BoatLocationEncoder implements MessageEncoder {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
public BoatLocationEncoder() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] encode(AC35Data message) {
|
||||||
|
|
||||||
|
//Downcast.
|
||||||
|
BoatLocation boatLocation = (BoatLocation) message;
|
||||||
|
|
||||||
|
|
||||||
|
int messageVersionNumber = 0b1;
|
||||||
|
byte[] messageVersionBytes = intToBytes(messageVersionNumber, 1);
|
||||||
|
byte[] time = longToBytes(boatLocation.getTime(), 6);
|
||||||
|
byte[] sourceID = intToBytes(boatLocation.getSourceID(), 4);
|
||||||
|
byte[] seqNum = longToBytes(boatLocation.getSequenceNumber(), 4);
|
||||||
|
byte[] deviceType = intToBytes(boatLocation.getDeviceType(), 1);
|
||||||
|
byte[] latitude = intToBytes(boatLocation.getLatitude(), 4);
|
||||||
|
byte[] longitude = intToBytes(boatLocation.getLongitude(), 4);
|
||||||
|
byte[] altitude = intToBytes(boatLocation.getAltitude(), 4);
|
||||||
|
byte[] heading = intToBytes(boatLocation.getHeading(), 2);
|
||||||
|
byte[] pitch = intToBytes(boatLocation.getPitch(), 2);
|
||||||
|
byte[] roll = intToBytes(boatLocation.getRoll(), 2);
|
||||||
|
byte[] boatSpeed = intToBytes(boatLocation.getBoatSpeed(), 2);
|
||||||
|
byte[] cog = intToBytes(boatLocation.getBoatCOG(), 2);
|
||||||
|
byte[] sog = intToBytes(boatLocation.getBoatSOG(), 2);
|
||||||
|
byte[] apparentWindSpeed = intToBytes(boatLocation.getApparentWindSpeed(), 2);
|
||||||
|
byte[] apparentWindAngle = intToBytes(boatLocation.getApparentWindAngle(), 2);
|
||||||
|
byte[] trueWindSpeed = intToBytes(boatLocation.getTrueWindSpeed(), 2);
|
||||||
|
byte[] trueWindDirection = intToBytes(boatLocation.getTrueWindDirection(), 2);
|
||||||
|
byte[] trueWindAngle = intToBytes(boatLocation.getTrueWindAngle(), 2);
|
||||||
|
byte[] currentDrift = intToBytes(boatLocation.getCurrentDrift(), 2);
|
||||||
|
byte[] currentSet = intToBytes(boatLocation.getCurrentSet(), 2);
|
||||||
|
byte[] rudderAngle = intToBytes(boatLocation.getRudderAngle(), 2);
|
||||||
|
|
||||||
|
ByteBuffer result = ByteBuffer.allocate(56);
|
||||||
|
result.put(messageVersionBytes);
|
||||||
|
result.put(time);
|
||||||
|
result.put(sourceID);
|
||||||
|
result.put(seqNum);
|
||||||
|
result.put(deviceType);
|
||||||
|
result.put(latitude);
|
||||||
|
result.put(longitude);
|
||||||
|
result.put(altitude);
|
||||||
|
result.put(heading);
|
||||||
|
result.put(pitch);
|
||||||
|
result.put(roll);
|
||||||
|
result.put(boatSpeed);
|
||||||
|
result.put(cog);
|
||||||
|
result.put(sog);
|
||||||
|
result.put(apparentWindSpeed);
|
||||||
|
result.put(apparentWindAngle);
|
||||||
|
result.put(trueWindSpeed);
|
||||||
|
result.put(trueWindDirection);
|
||||||
|
result.put(trueWindAngle);
|
||||||
|
result.put(currentDrift);
|
||||||
|
result.put(currentSet);
|
||||||
|
result.put(rudderAngle);
|
||||||
|
|
||||||
|
return result.array();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,6 +29,8 @@ public class EncoderFactory {
|
|||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|
||||||
|
case BOATLOCATION: return new BoatLocationEncoder();
|
||||||
|
|
||||||
case REQUEST_TO_JOIN: return new RequestToJoinEncoder();
|
case REQUEST_TO_JOIN: return new RequestToJoinEncoder();
|
||||||
|
|
||||||
case JOIN_ACCEPTANCE: return new JoinAcceptanceEncoder();
|
case JOIN_ACCEPTANCE: return new JoinAcceptanceEncoder();
|
||||||
|
|||||||
@@ -220,56 +220,6 @@ public class RaceVisionByteEncoder {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] boatLocation(BoatLocation boatLocation){
|
|
||||||
int messageVersionNumber = 0b1;
|
|
||||||
byte[] time = longToBytes(boatLocation.getTime(), 6);
|
|
||||||
byte[] sourceID = intToBytes(boatLocation.getSourceID(), 4);
|
|
||||||
byte[] seqNum = longToBytes(boatLocation.getSequenceNumber(), 4);
|
|
||||||
byte[] deviceType = intToBytes(boatLocation.getDeviceType(), 1);
|
|
||||||
byte[] latitude = intToBytes(boatLocation.getLatitude(), 4);
|
|
||||||
byte[] longitude = intToBytes(boatLocation.getLongitude(), 4);
|
|
||||||
byte[] altitude = intToBytes(boatLocation.getAltitude(), 4);
|
|
||||||
byte[] heading = intToBytes(boatLocation.getHeading(), 2);
|
|
||||||
byte[] pitch = intToBytes(boatLocation.getPitch(), 2);
|
|
||||||
byte[] roll = intToBytes(boatLocation.getRoll(), 2);
|
|
||||||
byte[] boatSpeed = intToBytes(boatLocation.getBoatSpeed(), 2);
|
|
||||||
byte[] cog = intToBytes(boatLocation.getBoatCOG(), 2);
|
|
||||||
byte[] sog = intToBytes(boatLocation.getBoatSOG(), 2);
|
|
||||||
byte[] apparentWindSpeed = intToBytes(boatLocation.getApparentWindSpeed(), 2);
|
|
||||||
byte[] apparentWindAngle = intToBytes(boatLocation.getApparentWindAngle(), 2);
|
|
||||||
byte[] trueWindSpeed = intToBytes(boatLocation.getTrueWindSpeed(), 2);
|
|
||||||
byte[] trueWindDirection = intToBytes(boatLocation.getTrueWindDirection(), 2);
|
|
||||||
byte[] trueWindAngle = intToBytes(boatLocation.getTrueWindAngle(), 2);
|
|
||||||
byte[] currentDrift = intToBytes(boatLocation.getCurrentDrift(), 2);
|
|
||||||
byte[] currentSet = intToBytes(boatLocation.getCurrentSet(), 2);
|
|
||||||
byte[] rudderAngle = intToBytes(boatLocation.getRudderAngle(), 2);
|
|
||||||
|
|
||||||
ByteBuffer result = ByteBuffer.allocate(56);
|
|
||||||
result.put(intToBytes(messageVersionNumber, 1));
|
|
||||||
result.put(time);
|
|
||||||
result.put(sourceID);
|
|
||||||
result.put(seqNum);
|
|
||||||
result.put(deviceType);
|
|
||||||
result.put(latitude);
|
|
||||||
result.put(longitude);
|
|
||||||
result.put(altitude);
|
|
||||||
result.put(heading);
|
|
||||||
result.put(pitch);
|
|
||||||
result.put(roll);
|
|
||||||
result.put(boatSpeed);
|
|
||||||
result.put(cog);
|
|
||||||
result.put(sog);
|
|
||||||
result.put(apparentWindSpeed);
|
|
||||||
result.put(apparentWindAngle);
|
|
||||||
result.put(trueWindSpeed);
|
|
||||||
result.put(trueWindDirection);
|
|
||||||
result.put(trueWindAngle);
|
|
||||||
result.put(currentDrift);
|
|
||||||
result.put(currentSet);
|
|
||||||
result.put(rudderAngle);
|
|
||||||
return result.array();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] markRounding(int time, int ackNumber, int raceID, int sourceID, int boatStatus, int roundingSide, int markType, int markID){
|
public static byte[] markRounding(int time, int ackNumber, int raceID, int sourceID, int boatStatus, int roundingSide, int markType, int markID){
|
||||||
int messageVersionNumber = 0b1;
|
int messageVersionNumber = 0b1;
|
||||||
byte[] byteTime = longToBytes(time, 6);
|
byte[] byteTime = longToBytes(time, 6);
|
||||||
|
|||||||
@@ -7,23 +7,52 @@ import org.junit.Test;
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by hba56 on 23/04/17.
|
* Test for the BoatLocation encoder and decoder
|
||||||
*/
|
*/
|
||||||
public class BoatLocationDecoderTest {
|
public class BoatLocationDecoderTest {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a BoatLocation message, encodes it, decodes it, and checks that the result matches the starting message.
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void getByteArrayTest(){
|
public void getByteArrayTest() throws Exception {
|
||||||
|
|
||||||
|
//Create message.
|
||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
BoatLocation testMessage = new BoatLocation((byte) 1, time, 2,
|
|
||||||
3, (byte) 1, 180, -180, 4, 5,
|
|
||||||
(short) 6, (short) 7, 8, 9, 10, 11,
|
|
||||||
(short) 12, 13, 14 , (short) 15,
|
|
||||||
16, 17, (short) 18);
|
|
||||||
|
|
||||||
byte [] testEncodedMessage = RaceVisionByteEncoder.boatLocation(testMessage);
|
BoatLocation testMessage = new BoatLocation(
|
||||||
|
(byte) 1,
|
||||||
|
time,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
(byte) 1,
|
||||||
|
180,
|
||||||
|
-180,
|
||||||
|
4,
|
||||||
|
5,
|
||||||
|
(short) 6,
|
||||||
|
(short) 7,
|
||||||
|
8,
|
||||||
|
9,
|
||||||
|
10,
|
||||||
|
11,
|
||||||
|
(short) 12,
|
||||||
|
13,
|
||||||
|
14,
|
||||||
|
(short) 15,
|
||||||
|
16,
|
||||||
|
17,
|
||||||
|
(short) 18 );
|
||||||
|
|
||||||
|
//Encode.
|
||||||
|
byte [] testEncodedMessage = RaceVisionByteEncoder.encode(testMessage);
|
||||||
|
|
||||||
|
//Decode.
|
||||||
BoatLocationDecoder testDecoder = new BoatLocationDecoder(testEncodedMessage);
|
BoatLocationDecoder testDecoder = new BoatLocationDecoder(testEncodedMessage);
|
||||||
BoatLocation decodedTest = testDecoder.getMessage();
|
BoatLocation decodedTest = testDecoder.getMessage();
|
||||||
|
|
||||||
|
//Check if valid.
|
||||||
Assert.assertEquals(testMessage.getMessageVersionNumber(), decodedTest.getMessageVersionNumber());
|
Assert.assertEquals(testMessage.getMessageVersionNumber(), decodedTest.getMessageVersionNumber());
|
||||||
Assert.assertEquals(testMessage.getTime(), decodedTest.getTime());
|
Assert.assertEquals(testMessage.getTime(), decodedTest.getTime());
|
||||||
Assert.assertEquals(testMessage.getSequenceNumber(), decodedTest.getSequenceNumber());
|
Assert.assertEquals(testMessage.getSequenceNumber(), decodedTest.getSequenceNumber());
|
||||||
|
|||||||
Reference in New Issue
Block a user