Commit f5926bea authored by garciay's avatar garciay
Browse files

STF507 Week#11: Merge GNSS support from C2C branch

parent 0d9e472b
......@@ -31,6 +31,9 @@
*/
package org.etsi.adapter;
import java.math.BigInteger;
import org.etsi.its.adapter.ports.AdapterPort;
import org.etsi.ttcn.tri.TriStatus;
/**
......@@ -63,6 +66,33 @@ public interface IGnssSupport {
*/
public boolean stopScenario();
/**
* Signals when the requested distance was covered
* @param distance The requested distance in m.
* @return TRUE on success, FALSE otherwise
*/
public boolean awaitDistanceToCover(AdapterPort notifier, double distance);
/**
* Changes dynamically the speed in the running scenario
* @param The new speed value.
* @return TRUE on success, FALSE otherwise
*/
public boolean changeSpeed(double speed);
/**
* Changes dynamically the heading in the running scenario
* @param heading The new heading value.
* @return TRUE on success, FALSE otherwise
*/
public boolean changeHeading(double heading);
/**
* Gets the current GPS time
* @return the time
*/
public BigInteger getGpsTime();
/**
* Dispose object
*/
......
......@@ -112,11 +112,18 @@ public class SecurityHelper {
return null;
}
}
byte[] aaSigningPublicKeyX, aaSigningPublicKeyY;
aaSigningPublicKeyX = ByteHelper.extract(certificateKeys.toByteArray(), 0, 32);
System.out.println("SecurityHelper.checkSecuredProfileAndExtractPayload: aaSigningPublicKeyX:" + ByteHelper.byteArrayToString(aaSigningPublicKeyX));
aaSigningPublicKeyY = ByteHelper.extract(certificateKeys.toByteArray(), 32, 32);
System.out.println("SecurityHelper.checkSecuredProfileAndExtractPayload: aaSigningPublicKeyX:" + ByteHelper.byteArrayToString(aaSigningPublicKeyX));
byte[] aaSigningPublicKeyX = null, aaSigningPublicKeyY = null;
byte[] keys = certificateKeys.toByteArray();
if ((keys[0] == 0x02) || (keys[0] == 0x03)) { // Key length = 32 bytes
aaSigningPublicKeyX = ByteHelper.extract(keys, 1, 32);
System.out.println("SecurityHelper.checkSecuredProfileAndExtractPayload: aaSigningPublicKeyX:" + ByteHelper.byteArrayToString(aaSigningPublicKeyX));
} else { // Key length = 64 bytes
aaSigningPublicKeyX = ByteHelper.extract(keys, 1, 32);
System.out.println("SecurityHelper.checkSecuredProfileAndExtractPayload: aaSigningPublicKeyX:" + ByteHelper.byteArrayToString(aaSigningPublicKeyX));
aaSigningPublicKeyY = ByteHelper.extract(keys, 33, 32);
System.out.println("SecurityHelper.checkSecuredProfileAndExtractPayload: aaSigningPublicKeyX:" + ByteHelper.byteArrayToString(aaSigningPublicKeyX));
}
// FIXME Add encryption support
System.out.println("SecurityHelper.checkSecuredProfileAndExtractPayload: headerFields:" + ByteHelper.byteArrayToString(headerFields));
// Extract payload, decvalue is updated with the payload
if (decvalue.read() != 1) {
......@@ -149,12 +156,14 @@ public class SecurityHelper {
p_message.length - (int)(p_offset + secureTrailerLength - 1 /* Exclude signature structure but keep signature type and signature length */)
);
System.out.println("SecurityHelper.checkSecuredProfileAndExtractPayload:" + ByteHelper.byteArrayToString(toBeVerifiedData));
// Calculate Digest digest from the buffer toBeVerifiedData
byte[] hash = CryptoLib.hashWithSha256(toBeVerifiedData);
boolean result;
try {
if (aaSigningPublicKeyY == null) {
// FIXME FSCOM: Check how t verify compressed signature
return payload;
}
result = CryptoLib.verifyWithEcdsaNistp256WithSha256(
hash,
toBeVerifiedData,
signature.toByteArray(),
aaSigningPublicKeyX,
aaSigningPublicKeyY
......@@ -163,7 +172,8 @@ public class SecurityHelper {
if (!result) {
// Drop packet
System.out.println("SecurityHelper.checkSecuredProfileAndExtractPayload: toBeVerifiedData :" + ByteHelper.byteArrayToString(toBeVerifiedData));
System.out.println("SecurityHelper.checkSecuredProfileAndExtractPayload: Hash :" + ByteHelper.byteArrayToString(hash));
// Calculate Digest digest from the buffer toBeVerifiedData
System.out.println("SecurityHelper.checkSecuredProfileAndExtractPayload: Hash :" + ByteHelper.byteArrayToString(CryptoLib.hashWithSha256(toBeVerifiedData)));
System.out.println("SecurityHelper.checkSecuredProfileAndExtractPayload: signature :" + ByteHelper.byteArrayToString(signature.toByteArray()));
System.out.println("SecurityHelper.checkSecuredProfileAndExtractPayload: aaSigningPublicKeyX:" + ByteHelper.byteArrayToString(aaSigningPublicKeyX));
System.out.println("SecurityHelper.checkSecuredProfileAndExtractPayload: aaSigningPublicKeyY:" + ByteHelper.byteArrayToString(aaSigningPublicKeyY));
......@@ -404,11 +414,24 @@ public class SecurityHelper {
ByteArrayInputStream subjectAttributes = new ByteArrayInputStream(b);
if (subjectAttributes.read() == 0x00) { // Subject Attribute: verification key (0) - Mandatory
if (subjectAttributes.read() == 0x00) { // Public Key Alg: ecdsa nistp256 with sha256 (0)
if (subjectAttributes.read() == 0x04) { // ECC Point Type: uncompressed (4)
byte v = (byte) subjectAttributes.read();
p_keys.write(v);
System.out.println("SecurityHelper.decodeCertificate: ECC Point Type: =" + v);
if (v == 0x02) { // ECC Point Type: compressed lsb y-0(2)
byte[] key = new byte[32];
subjectAttributes.read(key, 0, 32);
System.out.println("SecurityHelper.decodeCertificate: Verification lsb y-1 key=" + ByteHelper.byteArrayToString(key));
p_keys.write(key);
} else if (v == 0x03) { // ECC Point Type: compressed lsb y-1(3)
byte[] key = new byte[32];
subjectAttributes.read(key, 0, 32);
System.out.println("SecurityHelper.decodeCertificate: Verification lsb y-1 key=" + ByteHelper.byteArrayToString(key));
p_keys.write(key);
} else if (v == 0x04) { // ECC Point Type: uncompressed (4)
byte[] key = new byte[32];
subjectAttributes.read(key, 0, 32);
System.out.println("SecurityHelper.decodeCertificate: Verification key1=" + ByteHelper.byteArrayToString(key));
p_keys.write(key);
subjectAttributes.read(key, 0, 32);
System.out.println("SecurityHelper.decodeCertificate: Verification key2=" + ByteHelper.byteArrayToString(key));
p_keys.write(key);
......@@ -421,14 +444,27 @@ public class SecurityHelper {
if (v == 0x01) { // // Subject Attribute: encryption key (1)
if (subjectAttributes.read() == 0x01) { // Public Key Alg: ecdsa nistp256 (1)
if (subjectAttributes.read() == 0x00) { // Symmetric Algorithm: aes 128 ccm (0)
if (subjectAttributes.read() == 0x04) { // ECC Point Type: uncompressed (4)
v = (byte) subjectAttributes.read();
p_keys.write(v);
System.out.println("SecurityHelper.decodeCertificate: ECC Point Type: =" + v);
if (v == 0x02) { // ECC Point Type: compressed lsb y-0(2)
byte[] key = new byte[32];
subjectAttributes.read(key, 0, 32);
System.out.println("SecurityHelper.decodeCertificate: Encryption lsb y-0 key=" + ByteHelper.byteArrayToString(key));
p_keys.write(key);
} else if (v == 0x03) { // ECC Point Type: compressed lsb y-1(3)
byte[] key = new byte[32];
subjectAttributes.read(key, 0, 32);
System.out.println("SecurityHelper.decodeCertificate: Encryption lsb y-1 key=" + ByteHelper.byteArrayToString(key));
p_keys.write(key);
} else if (v == 0x04) { // ECC Point Type: uncompressed (4)
byte[] key = new byte[32];
subjectAttributes.read(key, 0, 32);
System.out.println("SecurityHelper.decodeCertificate: Encryption key1=" + ByteHelper.byteArrayToString(key));
//p_keys.write(key);
p_keys.write(key);
subjectAttributes.read(key, 0, 32);
System.out.println("SecurityHelper.decodeCertificate: Encryption key2=" + ByteHelper.byteArrayToString(key));
//p_keys.write(key);
p_keys.write(key);
} // FIXME To be continued
} // FIXME To be continued
} // FIXME To be continued
......@@ -670,7 +706,8 @@ public class SecurityHelper {
int secureTrailerIndex = 0;
if (p_secureTrailer[secureTrailerIndex++] == 0x01) { // Trailer Type: signature (1)
if (p_secureTrailer[secureTrailerIndex++] == 0x00) { // Public Key Alg: ecdsa nistp256 with sha256 (0)
if (p_secureTrailer[secureTrailerIndex++] == 0x02) { // ECC Point Type: compressed lsb y-0 (2)
byte v = p_secureTrailer[secureTrailerIndex++];
if ((v == 0x00) || (v == 0x02)) { // ECC Point Type: compressed lsb y-0 (2)
if (p_secureTrailer.length == (3 + 2 * 32)) {
// Build the signature vector
try {
......
......@@ -418,7 +418,7 @@ public class GnLayer extends Layer implements Runnable, IEthernetSpecific {
// Other messages
if(payloadLength > 0) {
byte[] mpayload = new byte[payloadLength];
System.arraycopy(payload, commonHdr.length + 28/*Topology-Scoped Broadcast*/, mpayload, 0, payloadLength);
System.arraycopy(payload, commonHdr.length + 44/*Topology-Scoped Broadcast*/, mpayload, 0, payloadLength);
// System.out.println("GnLayer.receive: Message =" + ByteHelper.byteArrayToString(mpayload));
lowerInfo.put(GN_NEXTHEADER, nextHeader);
lowerInfo.put(GN_TYPE, headerType);
......
......@@ -30,7 +30,8 @@ public class AdapterControlPort extends AdapterPort implements IPort, IObservabl
/* AdapterControl Response */
private static final byte AcGnResponse = 0;
//private static final byte AcGn6Response = 1;
private static final byte AcGnssResponse = 2;
public static final byte AcGnssResponse = 2;
public static final byte AcGnssDistanceCovered = 3;
/* GN Commands */
private static final byte AcStartBeaconing = 0;
......@@ -51,9 +52,12 @@ public class AdapterControlPort extends AdapterPort implements IPort, IObservabl
private static final byte AcLoadScenario = 0x70;
private static final byte AcStartScenario = 0x71;
private static final byte AcStopScenario = 0x72;
private static final byte AcAwaitDistanceToCover = 0x73;
private static final byte AcChangeSpead = 0x74;
private static final byte AcChangeHeading = 0x75;
protected static final byte AcTrue = 0x01;
protected static final byte AcFalse = 0x00;
public static final byte AcTrue = 0x01;
public static final byte AcFalse = 0x00;
private static final String GNSS_SCENARIO_SUPPORT = "GnssScenarioSupport";
private IGnssSupport GNSS;
......@@ -150,7 +154,7 @@ public class AdapterControlPort extends AdapterPort implements IPort, IObservabl
byte[] data = ByteHelper.extract(message, 2, message.length - 2);
switch (message[1]) {
case AcLoadScenario:
LoadScenario(data[0]);
LoadScenario(ByteHelper.byteArrayToShort(data));
break;
case AcStartScenario:
StartScenario();
......@@ -158,6 +162,16 @@ public class AdapterControlPort extends AdapterPort implements IPort, IObservabl
case AcStopScenario:
StopScenario();
break;
case AcAwaitDistanceToCover:
Float distance = ByteHelper.byteArrayToFloat(data);
AwaitDistanceToCover(distance);
break;
case AcChangeSpead:
// ChangeSpeed(speed);
break;
case AcChangeHeading:
// ChangeHeading(heading);
break;
}
}
else {
......@@ -256,6 +270,19 @@ public class AdapterControlPort extends AdapterPort implements IPort, IObservabl
}).start();
}
private void AwaitDistanceToCover(final double distance) {
new Thread(new Runnable() {
@Override
public void run() {
boolean result = GNSS.awaitDistanceToCover(AdapterControlPort.this, distance);
byte[] response = {(byte)AcGnssResponse, (byte)(result?AcFalse:AcTrue)};
setChanged();
notifyObservers(new PortEvent(response, getPortName(), getComponentName()));
}
}).start();
}
@Override
public void dispose() {
if (gnssScenarioSupport) {
......
......@@ -45,7 +45,7 @@ public abstract class AdapterPort implements IPort, IObservable {
/**
* Marks this Observable object as having been changed
*/
protected void setChanged() {
public void setChanged() {
observable.setChanged();
}
......
package org.etsi.ttcn.codec.its.adapter;
import org.etsi.ttcn.codec.CodecBuffer;
import org.etsi.ttcn.codec.MainCodec;
import org.etsi.ttcn.codec.generic.Boolean;
import org.etsi.ttcn.tci.Type;
import org.etsi.ttcn.tci.Value;
public class AcGnssAwaitDistanceCovered extends Boolean {
private static final int AcGnssDistanceCovered = 0x03;
public AcGnssAwaitDistanceCovered(MainCodec mainCodec) {
super(mainCodec);
}
@Override
public Value decode(CodecBuffer buf, Type decodingHypothesis) {
byte[] readId = buf.readBytes(1);
if(readId[0] != AcGnssDistanceCovered) {
return null;
}
return super.decode(buf, decodingHypothesis);
}
@Override
public CodecBuffer preEncode(Value value) {
return new CodecBuffer(new byte[] {0x02});
}
}
......@@ -35,6 +35,15 @@ public class AcGnssPrimitive extends Union {
case 0x72:
primitive = "stopScenario";
break;
case 0x73:
primitive = "distanceToCover";
break;
case 0x74:
primitive = "changeSpeed";
break;
case 0x75:
primitive = "changeHeading";
break;
}
mainCodec.setHint(decodingHypothesis.getName(), primitive);
......@@ -45,7 +54,6 @@ public class AcGnssPrimitive extends Union {
String variant = uv.getPresentVariantName();
int primitiveId = -1;
// Append AcDenmPrimitive message id
buf.appendBytes(ByteHelper.intToByteArray(2, 1));
// Append primitive id
......@@ -59,6 +67,15 @@ public class AcGnssPrimitive extends Union {
else if(variant.equals("stopScenario")) {
primitiveId = 0x72;
}
else if(variant.equals("distanceToCover")) {
primitiveId = 0x73;
}
else if(variant.equals("changeSpeed")) {
primitiveId = 0x74;
}
else if(variant.equals("changeHeading")) {
primitiveId = 0x75;
}
buf.appendBytes(ByteHelper.intToByteArray(primitiveId, 1));
}
}
......@@ -16,6 +16,9 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.logging.Logger;
import org.etsi.adapter.GnssSupportFactory;
import org.etsi.adapter.IGnssSupport;
import org.etsi.adapter.TERFactory;
import org.etsi.certificates.CertificatesIOFactory;
import org.etsi.certificates.io.ICertificatesIO;
import org.etsi.codec.ITciCDWrapper;
......@@ -67,6 +70,10 @@ public class ItsExternalFunctionsProvider implements IItsExternalFunctionsProvid
private static final long ITS_REF_TIME = 1072915200000L;
private static final String GNSS_SCENARIO_SUPPORT = "GnssScenarioSupport";
private IGnssSupport GNSS;
private boolean gnssScenarioSupport;
/**
* Reference to the ePassport files manager
*/
......@@ -80,6 +87,16 @@ public class ItsExternalFunctionsProvider implements IItsExternalFunctionsProvid
String.format("version:%s", Version));
_tcicdWrapper = TciCDWrapperFactory.getTciCDInstance();
try {
gnssScenarioSupport = ((BooleanValue) TERFactory.getInstance().getTaParameter(GNSS_SCENARIO_SUPPORT)).getBoolean();
}
catch (Throwable th) {
gnssScenarioSupport = false;
}
if (gnssScenarioSupport) {
GNSS = GnssSupportFactory.getInstance();
}
}
/**
......@@ -92,11 +109,15 @@ public class ItsExternalFunctionsProvider implements IItsExternalFunctionsProvid
*/
@Override
public synchronized IntegerValue fx_getCurrentTime() {
IntegerValue now = null;
_logger.entering("ItsExternalFunctionsProvider", "fx_getCurrentTime");
if (gnssScenarioSupport) {
now = _tcicdWrapper.setInteger(GNSS.getGpsTime());
}
else {
String datestr="01/01/2004 00:00:00 +0000";
DateFormat formatter = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss Z");
IntegerValue now = null;
try {
// System.out.println("ItsExternalFunctionsProvider.fx_getCurrentTime: " + ((java.util.Date)formatter.parse(datestr)).getTime());
now = _tcicdWrapper.setInteger(
......@@ -110,6 +131,7 @@ public class ItsExternalFunctionsProvider implements IItsExternalFunctionsProvid
}
_logger.exiting("ItsExternalFunctionsProvider", "fx_getCurrentTime", String.format("%10d", _tcicdWrapper.getBigInteger(now)));
}
return now;
} // End of method fx_getCurrentTime
......
/*
* ----------------------------------------------------------------------------
* (C) Copyright Testing Technologies, 2001-2015. All Rights Reserved.
* (C) Copyright Testing Technologies, 2001-2016. All Rights Reserved.
*
* All copies of this program, whether in whole or in part, and whether
* modified or not, must display this and all other embedded copyright
......@@ -30,7 +30,16 @@ package org.etsi.its.tool.testingtech;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
......@@ -38,22 +47,37 @@ import javax.xml.parsers.SAXParserFactory;
import org.etsi.adapter.IGnssSupport;
import org.etsi.adapter.TERFactory;
import org.etsi.common.ByteHelper;
import org.etsi.its.adapter.ports.AdapterControlPort;
import org.etsi.its.adapter.ports.AdapterPort;
import org.etsi.its.adapter.ports.PortEvent;
import org.etsi.ttcn.tci.CharstringValue;
import org.etsi.ttcn.tri.TriStatus;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import com.testingtech.ttcn.tci.codec.tabular.TabularDecoder;
import com.testingtech.ttcn.tci.codec.tabular.TabularException;
import com.testingtech.ttcn.tri.TriStatusImpl;
import com.testingtech.util.BitArrayInputStream;
import com.testingtech.util.BitArrayInputStream.Endianness;
import com.testingtech.util.ReferenceObject;
public class GnssRemoteControl implements IGnssSupport {
private final String STATUS_START = "<status>";
private final String STATUS_END = "</status>";
private final String DATA_START = "<data>";
private final String DATA_END = "</data>";
private Socket soc = null;
private static Boolean receiverRunning = false;
private static GnssRemoteControl gnssRC = null;
private boolean debug = true;
public static GnssRemoteControl getInstance() {
if (gnssRC == null){
gnssRC = new GnssRemoteControl();
......@@ -67,31 +91,23 @@ public class GnssRemoteControl implements IGnssSupport {
public static void main(String[] args) {
try {
for (int i = 0; i < 10; i++) {
for (int i = 0; i < 1; i++) {
GnssRemoteControl grc = GnssRemoteControl.getInstance();
grc.showMessage("Now controlled by TTwborkbench");
grc.loadScenario(0);
grc.loadScenario(1500);
// grc.getScenarioName();
// grc.getScenarioStatus();
// grc.getScenarioDuration();
grc.startScenario();
// grc.awaitDistanceToCover(new AdapterControlPort("test", "TestComp"), 200.0);
grc.getGpsTime();
// grc.getScenarioStatus();
Thread.sleep(2000);
grc.stopScenario();
// grc.getScenarioStatus();
}
} catch (Throwable th) {
th.printStackTrace();
}
finally {
// try {
// if (soc!=null) {
// soc.close();
// }
// } catch (IOException e) {
// e.printStackTrace();
// }
}
}
public void dispose() {
......@@ -118,18 +134,20 @@ public class GnssRemoteControl implements IGnssSupport {
// result = "c:\\Program Files (x86)\\Spirent Communications\\Positioning Application\\Scenarios\\C2C\\StaticPos\\StaticPos.scn";
scenario = "GnssScenario_StaticPos";
break;
case 1:
case 200:
// result = "C:\\Program Files (x86)\\Spirent Communications\\Positioning Application\\Scenarios\\C2C\\DynamicPos1000m\\DynamicPos200m.scn";
scenario = "GnssScenario_DynamicPos200m";
break;
case 2:
case 1000:
// result = "C:\\Program Files (x86)\\Spirent Communications\\Positioning Application\\Scenarios\\C2C\\DynamicPos1000m\\DynamicPos1000m.scn";
scenario = "GnssScenario_DynamicPos1000m";
break;
case 3:
// result = "C:\\Program Files (x86)\\Spirent Communications\\Positioning Application\\Scenarios\\C2C\\DynamicPos1000m\\DynamicPos1500m.scn";
case 1500:
// return "C:\\Program Files (x86)\\Spirent Communications\\Positioning Application\\Scenarios\\C2C\\DynamicPos1500m\\DynamicPos1500m.scn";
scenario = "GnssScenario_DynamicPos1500m";
break;
// case 4:
// return "C:\\Program Files (x86)\\Spirent Communications\\Positioning Application\\Scenarios\\C2C\\DynamicPos1500m_straight\\DynamicPos1500m_straight.scn";
default:
throw new Exception(p_id + ": Unknown scenario identification");
}
......@@ -150,11 +168,8 @@ public class GnssRemoteControl implements IGnssSupport {
public boolean loadScenario(int p_id) {
try {
// handleCommand("DS_ENABLE");
// handleCommand("DS_IP,192.168.89.227");
// handleCommand("DS_INFO");
// handleCommand("DS_STATUS,1");
return 2 == handleCommand("SC,"+getScenario(p_id));
boolean result= 2 == handleCommand("SC,"+getScenario(p_id));
return result && enableDataStreaming();
} catch (Throwable th) {
th.printStackTrace();
return false;
......@@ -173,34 +188,222 @@ public class GnssRemoteControl implements IGnssSupport {
return handleCommand("NULL");
}
// public int startScenario() {
public boolean enableDataStreaming() {
String address;
try {
try {
address = ((CharstringValue)TERFactory.getInstance().getTaParameter("TestSystemIpAddress")).getString();
}
catch (Throwable th) {
address = "10.73.100.38";
}
}
catch (Throwable th) {
th.printStackTrace();
return false;
}
boolean result = 2==handleCommand("DS_ENABLE,1");
handleCommand("DS_INFO");
if (result) {
result = 2==handleCommand("DS_IP,"+address);
}
if (result) {
result = 2==handleCommand("DS_VEH_MOT,v1,1");
}
if (result) {
result = 2==handleCommand("DS_VEH_CMS,v1,0");
}
if (result) {
result = 2==handleCommand("DS_SYNC,0");
}
if (result) {
result = 2==handleCommand("DS_STATUS,0");
}
if (result) {
result = 2==handleCommand("DS_ANT_MOT,v1_a1,0");
}
return result;
}
public boolean startScenario() {
// handleCommand("AR");
// try {
// Thread.sleep(5000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
int result = handleCommand("RU");
// try {
// Thread.sleep(5000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
if (result==4) {
while((result = getScenarioStatus())!=5){
//empty
try {
Thread.sleep(50);
} catch (InterruptedException e) {
//ignore
}