package net.gcdc.camdenm;
import static org.junit.Assert.assertEquals;
import net.gcdc.asn1.uper.UperEncoder;
import net.gcdc.camdenm.CoopIts.GenerationDeltaTime;
import net.gcdc.camdenm.CoopIts.ItsPduHeader;
import net.gcdc.camdenm.CoopIts.StationID;
import net.gcdc.camdenm.CoopIts.ItsPduHeader.MessageId;
import net.gcdc.camdenm.CoopIts.ItsPduHeader.ProtocolVersion;
import net.gcdc.camdenm.Iclcm;
import net.gcdc.camdenm.Iclcm.ControllerType;
import net.gcdc.camdenm.Iclcm.CruiseSpeed;
import net.gcdc.camdenm.Iclcm.EndOfScenario;
import net.gcdc.camdenm.Iclcm.IclmParameters;
import net.gcdc.camdenm.Iclcm.IgameCooperativeLaneChangeMessage;
import net.gcdc.camdenm.Iclcm.IgameCooperativeLaneChangeMessageBody;
import net.gcdc.camdenm.Iclcm.Lane;
import net.gcdc.camdenm.Iclcm.LaneObject;
import net.gcdc.camdenm.Iclcm.MergeObject;
import net.gcdc.camdenm.Iclcm.MioBearing;
import net.gcdc.camdenm.Iclcm.MioRange;
import net.gcdc.camdenm.Iclcm.MioRangeRate;
import net.gcdc.camdenm.Iclcm.MostImportantObjectContainer;
import net.gcdc.camdenm.Iclcm.PairIdObject;
import net.gcdc.camdenm.Iclcm.ParticipantsReady;
import net.gcdc.camdenm.Iclcm.ScenarioObject;
import net.gcdc.camdenm.Iclcm.StartPlatoon;
import net.gcdc.camdenm.Iclcm.TargetLongitudonalAcceleration;
import net.gcdc.camdenm.Iclcm.TimeHeadway;
import net.gcdc.camdenm.Iclcm.VehicleContainerHighFrequency;
import net.gcdc.camdenm.Iclcm.VehicleContainerLowFrequency;
import net.gcdc.camdenm.Iclcm.VehicleRearAxleLocation;
import net.gcdc.camdenm.Iclcm.VehicleResponseTime;
import net.gcdc.camdenm.Iclcm.VehicleResponseTimeConstant;
import net.gcdc.camdenm.Iclcm.VehicleResponseTimeDelay;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ICLCMTest {
private final static Logger logger = LoggerFactory.getLogger(UperEncoder.class);
@Test public void encodeParameterContainersVHF() {
//VehicleContainerHighFrequency
VehicleRearAxleLocation vehicleRearAxleLocation = new VehicleRearAxleLocation();
ControllerType controllerType = new ControllerType();
VehicleResponseTime vehicleResponseTime = new VehicleResponseTime();
TargetLongitudonalAcceleration targetLongitudinalAcceleration = new TargetLongitudonalAcceleration();
TimeHeadway timeHeadway = new TimeHeadway();
CruiseSpeed cruisespeed = new CruiseSpeed();
StationID stationID = new StationID(12345);
GenerationDeltaTime deltaTime = new GenerationDeltaTime(1480);
UperEncoder.encode(vehicleRearAxleLocation);
UperEncoder.encode(controllerType);
UperEncoder.encode(targetLongitudinalAcceleration);
UperEncoder.encode(timeHeadway);
UperEncoder.encode(cruisespeed);
byte[] encoded_responsetime = UperEncoder.encode(vehicleResponseTime);
logger.debug("hex: {}", getStringByteCode(encoded_responsetime));
logger.debug("data hex: {}", UperEncoder.hexStringFromBytes(encoded_responsetime));
byte[] encoded_deltaTime = UperEncoder.encode(deltaTime);
logger.debug("hex: {}", getStringByteCode(encoded_deltaTime));
logger.debug("data hex: {}", UperEncoder.hexStringFromBytes(encoded_deltaTime));
byte[] encoded_stationID = UperEncoder.encode(stationID);
logger.debug("hex: {}", getStringByteCode(encoded_stationID));
byte[] encoded_highFrequency=UperEncoder.encode(new VehicleContainerHighFrequency());
logger.debug("hex: {}", getStringByteCode(encoded_highFrequency));
logger.debug("bin out: {}", UperEncoder.hexStringFromBytes(encoded_highFrequency));
assertEquals("0003E9FA7E8DA67120",UperEncoder.hexStringFromBytes(encoded_highFrequency));
}
@Test public void test_encodeDecodeVehicleContainerHighFrequency(){
// Empty default message
byte[] encoded_highVelocity=UperEncoder.encode(new VehicleContainerHighFrequency());
logger.debug("hex: {}", getStringByteCode(encoded_highVelocity));
logger.debug("bin out: {}", UperEncoder.hexStringFromBytes(encoded_highVelocity));
assertEquals("0003E9FA7E8DA67120",UperEncoder.hexStringFromBytes(encoded_highVelocity));
VehicleContainerHighFrequency vf_filled = new VehicleContainerHighFrequency(
new VehicleRearAxleLocation(4095),
new ControllerType(ControllerType.cacc),
new VehicleResponseTime(
new VehicleResponseTimeConstant(VehicleResponseTimeConstant.oneSecond),
new VehicleResponseTimeDelay(VehicleResponseTimeDelay.oneSecond)),
new TargetLongitudonalAcceleration(0),
new TimeHeadway(TimeHeadway.oneSecond),
new CruiseSpeed(CruiseSpeed.oneMeterPerSecond));
byte[] encoded_vf_filled=UperEncoder.encode(vf_filled);
logger.debug("hex: {}", getStringByteCode(encoded_vf_filled));
logger.debug("bin out: {}", UperEncoder.hexStringFromBytes(encoded_vf_filled));
assertEquals("FFFC64191F40280C80",UperEncoder.hexStringFromBytes(encoded_vf_filled));
}
@Test public void test_encodeLowFrequencyContainer(){
ParticipantsReady participantsReady = new ParticipantsReady();//41
StartPlatoon startPlatoon = new StartPlatoon();//42
EndOfScenario endOfScenario = new EndOfScenario();//43
VehicleContainerLowFrequency lowfreq_empty = new VehicleContainerLowFrequency();
VehicleContainerLowFrequency lowfreq_filled_all= new VehicleContainerLowFrequency.Builder()
.participantsReady(participantsReady)
.startPlatoon(startPlatoon)
.endOfScenario(endOfScenario).create();
byte[] encoded_empty = UperEncoder.encode(lowfreq_empty);
byte[] encoded_full = UperEncoder.encode(lowfreq_filled_all);
logger.debug("bin empty: {}", UperEncoder.hexStringFromBytes(encoded_empty));
logger.debug("bin full: {}", UperEncoder.hexStringFromBytes(encoded_full));
assertEquals("00",UperEncoder.hexStringFromBytes(encoded_empty));
assertEquals("E0",UperEncoder.hexStringFromBytes(encoded_full));
}
@Test public void test_encodeDecodeMostImportantObjectContainer(){
MostImportantObjectContainer mioContainerDefault = new MostImportantObjectContainer(
new StationID(), new MioRange(), new MioBearing(), new MioRangeRate()
);
byte[] encoded_empty = UperEncoder.encode(mioContainerDefault);
logger.debug("bin: {}", UperEncoder.hexStringFromBytes(encoded_empty));
logger.debug("");
assertEquals("00000000FFFFC47FFFE0",UperEncoder.hexStringFromBytes(encoded_empty));
}
@Test public void test_encodeLaneObject(){
LaneObject lane_unavailable = new LaneObject(new Lane(Lane.unavailable));
LaneObject lane_one = new LaneObject(new Lane(Lane.laneOne));
byte[] encoded_empty = UperEncoder.encode(lane_unavailable);
byte[] encoded_one = UperEncoder.encode(lane_one);
logger.debug("bin-empty: {}", UperEncoder.hexStringFromBytes(encoded_empty));
logger.debug("");
assertEquals("C0",UperEncoder.hexStringFromBytes(encoded_empty));//Unavailable
assertEquals("00",UperEncoder.hexStringFromBytes(encoded_one));//One
}
@Test public void test_encodePairIdObject(){
PairIdObject pairObject = new PairIdObject();
byte[] encoded_empty = UperEncoder.encode(pairObject);
logger.debug("bin: {}", UperEncoder.hexStringFromBytes(encoded_empty));
logger.debug("");
assertEquals(UperEncoder.hexStringFromBytes(encoded_empty),"000000000000000000");
}
@Test public void test_encodeMergeObject(){
MergeObject obj = new MergeObject();
byte[] encoded_empty = UperEncoder.encode(obj);
logger.debug("bin: {}", UperEncoder.hexStringFromBytes(encoded_empty));
logger.debug("");
assertEquals(UperEncoder.hexStringFromBytes(encoded_empty),"00");
}
@Test public void test_encodeScenarioObject(){
ScenarioObject so = new ScenarioObject();
byte[] encoded_empty = UperEncoder.encode(so);
logger.debug("bin: {}", UperEncoder.hexStringFromBytes(encoded_empty));
logger.debug("");
assertEquals("03000000",UperEncoder.hexStringFromBytes(encoded_empty));
}
@Test public void test_encodeIclmParameters(){
VehicleContainerHighFrequency vehicleContainerHighFrequency = new VehicleContainerHighFrequency();
VehicleContainerLowFrequency lowFrequencyContainer = new VehicleContainerLowFrequency();
MostImportantObjectContainer mostImportantObjectContainer = new MostImportantObjectContainer();
LaneObject laneObject = new LaneObject();
PairIdObject pairIdObject = new PairIdObject();
MergeObject mergeObject = new MergeObject();
ScenarioObject scenarioObject = new ScenarioObject();
IclmParameters parameters = new IclmParameters(vehicleContainerHighFrequency,
lowFrequencyContainer,
mostImportantObjectContainer,
laneObject,
pairIdObject,
mergeObject,
scenarioObject);
byte[] encoded_empty = UperEncoder.encode(parameters);
//High freq: 1*10 bytes: 00 00 00 00 00 00 00 00 00 00
logger.debug("binary vehicleContainerHighFrequency: {}", UperEncoder.hexStringFromBytes(UperEncoder.encode(vehicleContainerHighFrequency)));
//ERROR! Low freq: 1*1 byte: 00
logger.debug("binary lowFrequencyContainer: {}", UperEncoder.hexStringFromBytes(UperEncoder.encode(lowFrequencyContainer)));
//MIO: 1* 11 bytes: 00 00 00 00 00 00 00 00 00 00 00
logger.debug("binary mostImportantObjectContainer: {}", UperEncoder.hexStringFromBytes(UperEncoder.encode(mostImportantObjectContainer)));
//Lane: 1* 1 byte: 00
logger.debug("binary laneObject: {}", UperEncoder.hexStringFromBytes(UperEncoder.encode(laneObject)));
//PairID: 1*9 bytes: 00 00 00 00 00 00 00 00 00
logger.debug("binary pairIdObject: {}", UperEncoder.hexStringFromBytes(UperEncoder.encode(pairIdObject)));
//Merge: 1*1 byte: 00
logger.debug("binary mergeObject: {}", UperEncoder.hexStringFromBytes(UperEncoder.encode(mergeObject)));
//Scen: 1* 4 byte: 00 00 00 00
logger.debug("binary scenarioObject: {}", UperEncoder.hexStringFromBytes(UperEncoder.encode(scenarioObject)));
//Parameters: 1*33 bytes: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
logger.debug("parameters: {}", UperEncoder.hexStringFromBytes(UperEncoder.encode(parameters)));
assertEquals("8001F4FD3F46D3389000000001FFFF88FFFFD8000000000000000000600000",UperEncoder.hexStringFromBytes(encoded_empty));
}
@Test public void test_encodeIgameCooperativeLaneChangeMessageBody(){
GenerationDeltaTime generationDeltaTime = new GenerationDeltaTime();
IclmParameters iclmParameters = new IclmParameters();
IgameCooperativeLaneChangeMessageBody body_ctor1 = new IgameCooperativeLaneChangeMessageBody();
IgameCooperativeLaneChangeMessageBody body_ctor2 = new IgameCooperativeLaneChangeMessageBody(generationDeltaTime,iclmParameters);
byte[] encoded_ctor1 = UperEncoder.encode(body_ctor1);
logger.debug("bin: {}", UperEncoder.hexStringFromBytes(encoded_ctor1));
logger.debug("");
//1*35 bytes
assertEquals("00640001F4FD3F46D338900000000FFFFC47FFFEC0000000000000000003000000",UperEncoder.hexStringFromBytes(encoded_ctor1));
byte[] encoded_ctor2 = UperEncoder.encode(body_ctor2);
logger.debug("bin: {}", UperEncoder.hexStringFromBytes(encoded_ctor2));
logger.debug("");
assertEquals("00640001F4FD3F46D338900000000FFFFC47FFFEC0000000000000000003000000",UperEncoder.hexStringFromBytes(encoded_ctor2));
}
@Test public void test_IgameCooperativeLaneChangeMessage() {
//NOTE: it is very important to specify ICLCM if pdu is constructed separately
//This test was written for the 1.0 version
final long protocolVersion = 1;//test is configured for this encoding
ItsPduHeader header = new ItsPduHeader(
new ProtocolVersion(protocolVersion),
new MessageId(Iclcm.MessageID_iCLCM),
new StationID());
IgameCooperativeLaneChangeMessageBody iclm = new IgameCooperativeLaneChangeMessageBody();
IgameCooperativeLaneChangeMessage message_default = new IgameCooperativeLaneChangeMessage();
IgameCooperativeLaneChangeMessage message_filled = new IgameCooperativeLaneChangeMessage(header,iclm);
byte[] encoded_header = UperEncoder.encode(header);
logger.debug("bin header: {}", UperEncoder.hexStringFromBytes(encoded_header));
assertEquals("010A00000000",UperEncoder.hexStringFromBytes(encoded_header));
byte[] encoded_default = UperEncoder.encode(message_default);
byte[] encoded_filled = UperEncoder.encode(message_filled);
logger.debug("bin default: {}", UperEncoder.hexStringFromBytes(encoded_default));
logger.debug("bin filled: {}", UperEncoder.hexStringFromBytes(encoded_filled));
assertEquals("010A0000000000640001F4FD3F46D338900000000FFFFC47FFFEC0000000000000000003000000",UperEncoder.hexStringFromBytes(encoded_filled));
}
/**
* Test the correct recoding of several 'valid' messages
*/
@Test public void test_KnownMessages(){
String[] encodedStrings = {
"01 0A 00 00 00 01 4F 8B 00 05 F4 FD 3F 46 D3 38 90 00 00 00 1F FF FC 47 FF FE C0 00 00 00 40 00 00 00 40 03 00 00 00",
"01 0A 00 00 00 03 8F 28 A5 86 32 02 94 A0 24 D0 29 00 00 00 01 05 DC 00 18 4A F0 00 00 00 04 00 00 00 0A 10 10 20 84",
"01 0A 00 00 00 03 EB 7B A5 86 32 02 94 A0 24 D0 2F 00 00 00 00 82 EE 00 0C 25 78 00 00 00 02 00 00 00 05 E8 10 10 4E",
"01 0A 00 00 00 0B 0D A4 00 07 F4 FD 3F 46 D3 38 90 00 00 00 2F FF FC 47 FF FE C0 00 00 00 40 00 00 00 40 03 00 00 00",
"010A00000002007B8326320C9F401406400000001607D102F031F00000007800000087E0200938",
"010A00000000000080000000000000000000000000000000000000000000000000000000000000",//min ranges
"010AFFFFFFFFFFFFFFFFF4FD3F46D33891FFFFFFFFFFFF88FFFFDFFFFFFFFFFFFFFFFFFFD38858"//max ranges
};
for(String s: encodedStrings){
String input = s.replace(" ", "");
IgameCooperativeLaneChangeMessage asMessage = UperEncoder.decode(UperEncoder.bytesFromHexString(input), IgameCooperativeLaneChangeMessage.class);
byte[] asBytes = UperEncoder.encode(asMessage);
assertEquals(UperEncoder.hexStringFromBytes(asBytes),input);
}
}
/**
* Utility: Byte array to readable hexadecimal representation
* @param data
* @return String with encoded hexadecimal representation
*/
public static String getStringByteCode(byte[] data){
StringBuilder sb = new StringBuilder();
for (byte b : data) {
sb.append(String.format("%02X ", b));
}
return sb.toString();
}
}