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.
217 lines
7.6 KiB
217 lines
7.6 KiB
package network.MessageEncoders;
|
|
|
|
|
|
import network.Exceptions.InvalidMessageException;
|
|
import network.Exceptions.InvalidMessageTypeException;
|
|
import network.Messages.*;
|
|
|
|
import static network.Utils.ByteConverter.*;
|
|
|
|
import java.nio.ByteBuffer;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
|
|
|
|
/**
|
|
* Created by fwy13 on 19/04/17.
|
|
*/
|
|
public class RaceVisionByteEncoder {
|
|
|
|
|
|
|
|
|
|
public static byte[] displayTextMessage(RaceMessage[] message){
|
|
//ByteBuffer result = ByteBuffer.allocate(4 + numLines * 32);
|
|
int messageVersionNumber = 0b1;//version number
|
|
short ackNum = 0;//no clue what this does just a placeholder for 2 bytes.
|
|
byte[] messLines = intToBytes(message.length, 1);
|
|
|
|
// result.putInt(messageVersionNumber);
|
|
// result.putShort(ackNum);
|
|
// result.put(messLines);
|
|
|
|
ArrayList<byte[]> messages = new ArrayList<byte[]>();
|
|
int size = 4;
|
|
|
|
for (int i = 0; i < message.length; i ++){
|
|
int messageLen = message[i].getMessageText().getBytes().length;
|
|
byte[] messageAsBytes = message[i].getMessageText().getBytes();
|
|
if (messageLen < 30){
|
|
messageLen = 30;
|
|
}
|
|
ByteBuffer mess = ByteBuffer.allocate(2 + messageLen);
|
|
mess.put(intToBytes(message[i].getLineNumber(), 1));
|
|
mess.put(intToBytes(messageLen, 1));
|
|
for (int j = 0; j < messageLen; j ++){
|
|
mess.put(messageAsBytes[j]);
|
|
}
|
|
messages.add(mess.array());
|
|
size += 2 + messageLen;
|
|
}
|
|
|
|
ByteBuffer result = ByteBuffer.allocate(size);
|
|
result.put(intToBytes(messageVersionNumber, 1));
|
|
result.putShort(ackNum);
|
|
result.put(messLines);
|
|
|
|
for(byte[] mess: messages){
|
|
result.put(mess);
|
|
}
|
|
|
|
return result.array();
|
|
}
|
|
|
|
public static byte[] raceStartStatus(long time, short ack, long startTime, int raceID, char notification){
|
|
int messageVersion = 0b1;
|
|
byte[] timestamp = longToBytes(time, 6);
|
|
byte[] ackNumber = intToBytes(ack, 2);
|
|
byte[] raceStartTime = longToBytes(startTime, 6);
|
|
int raceIdentifier = raceID;
|
|
byte[] notificationType = intToBytes(notification, 1);
|
|
|
|
ByteBuffer result = ByteBuffer.allocate(20);
|
|
result.put(intToBytes(messageVersion, 1));
|
|
result.put(timestamp);
|
|
result.put(ackNumber);
|
|
result.put(raceStartTime);
|
|
result.put(intToBytes(raceIdentifier));
|
|
result.put(notificationType);
|
|
|
|
return result.array();
|
|
}
|
|
|
|
public static byte[] yachtEventCode(long time, short acknowledgeNumber, int raceID, int destSourceID, int incidentID,
|
|
int eventID){
|
|
int messageVersion = 0b10;
|
|
byte[] encodeTime = longToBytes(time, 6);
|
|
short ackNum = acknowledgeNumber;
|
|
int raceUID = raceID;//TODO chekc if this is an into for a 4 char string.
|
|
int destSource = destSourceID;
|
|
int incident = incidentID;
|
|
byte[] event = intToBytes(eventID, 1);
|
|
|
|
ByteBuffer result = ByteBuffer.allocate(22);
|
|
result.put(intToBytes(messageVersion, 1));
|
|
result.put(encodeTime);
|
|
result.putShort(ackNum);
|
|
result.put(intToBytes(raceUID));
|
|
result.put(intToBytes(destSource));
|
|
result.put(intToBytes(incident));
|
|
result.put(event);
|
|
return result.array();
|
|
}
|
|
|
|
public static byte[] chatterText(int messageType, String message){
|
|
int messageVersion = 0b1;
|
|
byte[] type = intToBytes(messageType, 1);
|
|
byte[] text = message.getBytes();
|
|
byte[] length = intToBytes(text.length, 1);
|
|
|
|
ByteBuffer result = ByteBuffer.allocate(3 + text.length);
|
|
result.put(intToBytes(messageVersion, 1));
|
|
result.put(type);
|
|
result.put(length);
|
|
result.put(text);
|
|
|
|
return result.array();
|
|
}
|
|
|
|
|
|
public static byte[] markRounding(int time, int ackNumber, int raceID, int sourceID, int boatStatus, int roundingSide, int markType, int markID){
|
|
int messageVersionNumber = 0b1;
|
|
byte[] byteTime = longToBytes(time, 6);
|
|
byte[] byteAck = intToBytes(ackNumber, 2);
|
|
byte[] byteRaceID = intToBytes(raceID, 4);
|
|
byte[] byteSourceID = intToBytes(sourceID, 4);
|
|
byte[] byteBoatStatus = intToBytes(boatStatus, 1);
|
|
byte[] byteRoundingSide = intToBytes(roundingSide, 1);
|
|
byte[] byteMarkType = intToBytes(markType, 1);
|
|
byte[] byteMarkID = intToBytes(markID, 1);
|
|
|
|
ByteBuffer result = ByteBuffer.allocate(21);
|
|
result.put(intToBytes(messageVersionNumber, 1));
|
|
result.put(byteTime);
|
|
result.put(byteAck);
|
|
result.put(byteRaceID);
|
|
result.put(byteSourceID);
|
|
result.put(byteBoatStatus);
|
|
result.put(byteRoundingSide);
|
|
result.put(byteMarkType);
|
|
result.put(byteMarkID);
|
|
return result.array();
|
|
}
|
|
|
|
public static byte[] courseWind(byte windID, ArrayList<CourseWind> courseWinds){
|
|
int messageVersionNumber = 0b1;
|
|
byte byteWindID = windID;
|
|
byte[] loopcount = intToBytes(courseWinds.size(), 1);
|
|
ByteBuffer result = ByteBuffer.allocate(3 + 20 * courseWinds.size());
|
|
result.put(intToBytes(messageVersionNumber, 1));
|
|
result.put(byteWindID);
|
|
result.put(loopcount);
|
|
for (CourseWind wind: courseWinds){
|
|
result.put(intToBytes(wind.getID(), 1));
|
|
result.put(longToBytes(wind.getTime(), 6));
|
|
result.put(intToBytes(wind.getRaceID(), 4));
|
|
result.put(intToBytes(wind.getWindDirection(), 2));
|
|
result.put(intToBytes(wind.getWindSpeed(), 2));
|
|
result.put(intToBytes(wind.getBestUpwindAngle(), 2));
|
|
result.put(intToBytes(wind.getBestDownwindAngle(), 2));
|
|
result.put(intToBytes(wind.getFlags(), 1));
|
|
}
|
|
return result.array();
|
|
}
|
|
|
|
public static byte[] averageWind(int time, int rawPeriod, int rawSampleSpeed, int period2, int speed2, int period3, int speed3, int period4, int speed4){
|
|
int messageVersionNumber = 0b1;
|
|
byte[] byteTime = longToBytes(time,6);
|
|
byte[] byteRawPeriod = intToBytes(rawPeriod, 2);
|
|
byte[] byteRawSpeed = intToBytes(rawSampleSpeed, 2);
|
|
byte[] bytePeriod2 = intToBytes(period2, 2);
|
|
byte[] byteSpeed2 = intToBytes(speed2, 2);
|
|
byte[] bytePeriod3 = intToBytes(period3, 2);
|
|
byte[] byteSpeed3 = intToBytes(speed3, 2);
|
|
byte[] bytePeriod4 = intToBytes(period4, 2);
|
|
byte[] byteSpeed4 = intToBytes(speed4, 2);
|
|
|
|
ByteBuffer result = ByteBuffer.allocate(23);
|
|
result.put(intToBytes(messageVersionNumber, 1));
|
|
result.put(byteTime);
|
|
result.put(byteRawPeriod);
|
|
result.put(byteRawSpeed);
|
|
result.put(bytePeriod2);
|
|
result.put(byteSpeed2);
|
|
result.put(bytePeriod3);
|
|
result.put(byteSpeed3);
|
|
result.put(bytePeriod4);
|
|
result.put(byteSpeed4);
|
|
return result.array();
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Encodes a given message.
|
|
* @param message Message to encode.
|
|
* @return Encoded message.
|
|
* @throws InvalidMessageException If the message cannot be encoded.
|
|
*/
|
|
public static byte[] encode(AC35Data message) throws InvalidMessageException {
|
|
|
|
MessageEncoder encoder = null;
|
|
try {
|
|
encoder = EncoderFactory.create(message.getType());
|
|
} catch (InvalidMessageTypeException e) {
|
|
throw new InvalidMessageException("Could not create encoder for MessageType: " + message.getType(), e);
|
|
}
|
|
|
|
byte[] encodedMessage = encoder.encode(message);
|
|
|
|
return encodedMessage;
|
|
}
|
|
|
|
|
|
}
|