Added BoatLocationEncoder.

Updated BoatLocationDecoder test to use new encoder.
Updated MockOutput to use new encoder. It logs a warning if encoding fails.

#story[1095]
main
fjc40 9 years ago
parent 31ce9fff94
commit c3ed30019c

@ -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,12 +281,20 @@ public class MockOutput implements Runnable
BoatLocation boatLocation = this.latestMessages.getBoatLocation(sourceID); BoatLocation boatLocation = this.latestMessages.getBoatLocation(sourceID);
if (boatLocation != null) { if (boatLocation != null) {
try {
//Encode. //Encode.
byte[] boatLocationBlob = this.parseBoatLocation(boatLocation); byte[] boatLocationBlob = this.parseBoatLocation(boatLocation);
//Write it. //Write it.
this.outToVisualiser.write(boatLocationBlob); 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());

Loading…
Cancel
Save