Compare Revisions

The credentials to download the source code are:
 Username: svnusers
 Password: svnusers

Ignore whitespace Rev 2752 → Rev 2753

/branches/AMB/AdapterFramework/javasrc/extfunc/org/etsi/its/extfunc/ItsExternalFunctionsProvider.java
File deleted
Property changes:
Deleted: svn:keywords
## -1 +0,0 ##
-URL Author Date Rev Id
\ No newline at end of property
Index: AdapterFramework/javasrc/extfunc/org/etsi/extfunc/its/ItsExternalFunctionsProvider.java
===================================================================
--- AdapterFramework/javasrc/extfunc/org/etsi/extfunc/its/ItsExternalFunctionsProvider.java (nonexistent)
+++ AdapterFramework/javasrc/extfunc/org/etsi/extfunc/its/ItsExternalFunctionsProvider.java (revision 2753)
@@ -0,0 +1,923 @@
+/**
+ * @authorSTF 424_ITS_Test_Platform
+ * @version $URL$
+ * $Id$
+ */
+package org.etsi.extfunc.its;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.util.ArrayList;
+
+import org.etsi.ttcn.adapter.core.TestAdapter;
+import org.etsi.helpers.certificates.CertificatesIOFactory;
+import org.etsi.helpers.certificates.io.ICertificatesIO;
+import org.etsi.ttcn.codec.core.ITciCDWrapper;
+import org.etsi.ttcn.codec.core.TciCDWrapperFactory;
+import org.etsi.common.ByteHelper;
+import org.etsi.helpers.geodesic.DMS;
+import org.etsi.helpers.geodesic.Positioning;
+import org.etsi.helpers.geodesic.WGS84;
+import org.etsi.helpers.gnss.GnssSupportFactory;
+import org.etsi.helpers.gnss.IGnssSupport;
+import org.etsi.ttcn.tci.BooleanValue;
+import org.etsi.ttcn.tci.CharstringValue;
+import org.etsi.ttcn.tci.EnumeratedValue;
+import org.etsi.ttcn.tci.FloatValue;
+import org.etsi.ttcn.tci.IntegerValue;
+import org.etsi.ttcn.tci.OctetstringValue;
+import org.etsi.ttcn.tci.RecordOfValue;
+import org.etsi.ttcn.tci.RecordValue;
+
+import de.fraunhofer.sit.c2x.CryptoLib;
+import de.fraunhofer.sit.c2x.EcdsaP256KeyPair;
+
+/**
+ * This class implements external ITS function
+ *
+ * See TTCN-3 modules LibItsGeoNetworking_Functions and LibItsCommon_Functions
+ *
+ */
+public class ItsExternalFunctionsProvider {
+
+ /**
+ * Module version
+ */
+ public static final String Version = "1.0.0.0";
+
+ /**
+ * Unique instance of TciCDWrapper class
+ */
+ private ITciCDWrapper _tcicdWrapper;
+
+ /**
+ * Constant factor used for distance computation
+ */
+ private static final double earthRadius = 6378137;
+ private static final double rbis = earthRadius * Math.PI / 180;
+
+ 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
+ */
+ private ICertificatesIO _certCache = CertificatesIOFactory.getInstance();
+
+ /**
+ * Default ctor
+ */
+ public ItsExternalFunctionsProvider() {
+
+ _tcicdWrapper = TciCDWrapperFactory.getTciCDInstance();
+
+ try {
+ gnssScenarioSupport = TestAdapter.getTaParameter(GNSS_SCENARIO_SUPPORT).equalsIgnoreCase("true")?true:false;
+ }
+ catch (Throwable th) {
+ gnssScenarioSupport = false;
+ }
+ if (gnssScenarioSupport) {
+ GNSS = GnssSupportFactory.getInstance();
+ }
+ }
+
+ /**
+ * This external function gets the current time
+ *
+ * @return The current time in ITS format
+ *
+ * TTCN-3 signature: external function fx_getCurrentTime() return
+ * TimestampIts;
+ */
+ public synchronized IntegerValue fx_getCurrentTime() {
+ IntegerValue now = null;
+
+ if (gnssScenarioSupport) {
+ now = _tcicdWrapper.setInteger(GNSS.getGpsTime());
+ }
+ else {
+ now = _tcicdWrapper.setInteger(
+ new BigInteger(
+ 1,
+ ByteHelper.longToByteArray(System.currentTimeMillis() - ITS_REF_TIME, Long.SIZE / Byte.SIZE)
+ )
+ );
+ }
+ return now;
+ } // End of method fx_getCurrentTime
+
+ public IntegerValue fx_getCurrentTimeMark() {
+ IntegerValue now = null;
+
+ ZonedDateTime t = ZonedDateTime.now(ZoneOffset.UTC);
+ now = _tcicdWrapper.setInteger(new Integer((t.getMinute() * 60 + t.getSecond()) * 10));
+
+ return now;
+ }
+
+ public IntegerValue fx_getMinuteOfTheYear() {
+ IntegerValue now = null;
+
+ ZonedDateTime t = ZonedDateTime.now(ZoneOffset.UTC);
+ now = _tcicdWrapper.setInteger(new Integer((t.getDayOfYear() - 1) * 24 * 60 + t.getHour() * 60 + t.getMinute()));
+
+ return now;
+ }
+
+ public IntegerValue fx_getDSecond() {
+ IntegerValue now = null;
+
+ ZonedDateTime t = ZonedDateTime.now(ZoneOffset.UTC);
+ int i = new Integer(t.getSecond() + Math.round(t.getNano() / 1000));
+ if (i > 65535) {
+ i = 65535;
+ }
+ now = _tcicdWrapper.setInteger(i);
+
+ return now;
+ }
+
+ /**
+ * This external function gets the current time
+ *
+ * @param p_latitudeA
+ * Latitude of node A
+ * @param p_longitudeA
+ * Longitude of node A
+ * @param p_latitudeB
+ * Latitude of node B
+ * @param p_longitudeB
+ * Longitude of node B
+ * @return The current time in Epoch format
+ *
+ * TTCN-3 signature: external function fx_computeDistance(in UInt32
+ * p_latitudeA, in UInt32 p_longitudeA, in UInt32 p_latitudeB, in
+ * UInt32 p_longitudeB) return float;
+ */
+ public synchronized FloatValue fx_computeDistance(
+ final IntegerValue p_latitudeA, final IntegerValue p_longitudeA,
+ final IntegerValue p_latitudeB, final IntegerValue p_longitudeB) {
+
+ // Initialise the returned value
+ FloatValue dist = _tcicdWrapper.getFloat();
+
+ double dlat = (
+ new Double(_tcicdWrapper.getInteger(p_latitudeB)) -
+ new Double(_tcicdWrapper.getInteger(p_latitudeA))
+ ) / 10000000;
+ double dlong = (
+ new Double(_tcicdWrapper.getInteger(p_longitudeB)) -
+ new Double(_tcicdWrapper.getInteger(p_longitudeA))
+ ) / 10000000;
+
+ long d = Math.round(Math.sqrt(Math.pow(dlat * rbis, 2) + Math.pow(dlong * rbis * Math.cos(dlat), 2)));
+
+ dist.setFloat(d);
+
+ return dist;
+ } // End of method fx_computeDistance
+
+ /**
+ * External function to compute a position using a reference position, a
+ * distance and an orientation
+ *
+ * @param p_iutLongPosVector
+ * Reference position
+ * @param p_distance
+ * Distance to the reference position (in meter)
+ * @param p_orientation
+ * Direction of the computed position (0 to 359; 0 means North)
+ * @param p_latitude
+ * Computed position's latitude
+ * @param p_longitude
+ * Computed position's longitude
+ *
+ * TTCN-3 signature: external function
+ * fx_computePositionUsingDistance(in LongPosVector
+ * p_iutLongPosVector, in integer p_distance, in integer
+ * p_orientation, out UInt32 p_latitude, out UInt32 p_longitude);
+ */
+ public synchronized void fx_computePositionUsingDistance(
+ final IntegerValue p_refLatitude,
+ final IntegerValue p_refLongitude, final FloatValue p_distance,
+ final IntegerValue p_orientation, IntegerValue p_latitude,
+ IntegerValue p_longitude) {
+
+ FloatValue v_distance = _tcicdWrapper.getFloat();
+ v_distance.setFloat(p_distance.getFloat());
+ double angularD = new Double(v_distance.getFloat()) / earthRadius;
+ double radHeading = new Double(_tcicdWrapper.getInteger(p_orientation)) * Math.PI / 180;
+
+ // Convert to rad
+ double lat1 = (new Double(_tcicdWrapper.getInteger(p_refLatitude)) / 10000000) * Math.PI / 180;
+ double long1 = (new Double(_tcicdWrapper.getInteger(p_refLongitude)) / 10000000) * Math.PI / 180;
+
+ double lat2 = Math.asin(Math.sin(lat1) * Math.cos(angularD)
+ + Math.cos(lat1) * Math.sin(angularD) * Math.cos(radHeading));
+ double long2 = long1
+ + Math.atan2(
+ Math.sin(radHeading) * Math.sin(angularD)
+ * Math.cos(lat1),
+ Math.cos(angularD) - Math.sin(lat1) * Math.sin(lat2));
+
+ // normalise to -180...+180
+ long2 = (long2 + 3 * Math.PI) % (2 * Math.PI) - Math.PI;
+
+ // convert to 1/10 of microdegrees
+ Long rlat2 = Math.round(lat2 * 10000000 / Math.PI * 180);
+ Long rlong2 = Math.round(long2 * 10000000 / Math.PI * 180);
+
+ // The out parameter needs to be set on the object level
+ _tcicdWrapper.setInteger(p_latitude, rlat2.intValue());
+ _tcicdWrapper.setInteger(p_longitude, rlong2.intValue());
+// p_latitude = _tcicdWrapper.setInteger((int) rlat2);
+// p_longitude = _tcicdWrapper.setInteger((int) rlong2);
+
+ } // End of method fx_computePositionUsingDistance
+
+ /**
+ * External function to compute a position using a rotation
+ *
+ * @param p_iutLongPosVector
+ * Reference position
+ * @param p_rotation
+ * Rotation value (in degrees)
+ * @param p_latitude
+ * Computed position's latitude
+ * @param p_longitude
+ * Computed position's longitude
+ *
+ * TTCN-3 signature: external function
+ * fx_computePositionFromRotation(in LongPosVector
+ * p_iutLongPosVector, in Int32
+ * p_rotation, out Int32 p_latitude, out Int32 p_longitude);
+ * @remark See http://www.movable-type.co.uk/scripts/latlong.html
+ */
+ public synchronized void fx_computePositionFromRotation(
+ final IntegerValue p_refLatitude,
+ final IntegerValue p_refLongitude,
+ final IntegerValue p_cenLatitude,
+ final IntegerValue p_cenLongitude,
+ final IntegerValue p_rotation,
+ IntegerValue p_latitude,
+ IntegerValue p_longitude) {
+
+ // 1. Compute distance between the 2 points
+ double lat1 = Math.toRadians((double)_tcicdWrapper.getInteger(p_cenLatitude) / 10000000.0);
+ double long1 = Math.toRadians((double)_tcicdWrapper.getInteger(p_cenLongitude) / 10000000.0);
+ double lat2 = Math.toRadians((double)_tcicdWrapper.getInteger(p_refLatitude) / 10000000.0);
+ double long2 = Math.toRadians((double)_tcicdWrapper.getInteger(p_refLongitude) / 10000000.0);
+ double dlat = lat2 - lat1;
+ double dlong = long2 - long1;
+ double a = Math.sin(dlat / 2) * Math.sin(dlat / 2) + Math.cos(lat1) * Math.cos(lat2) * Math.sin(dlong / 2) * Math.sin(dlong / 2);
+ double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
+ //double d = earthRadius * c;
+
+ // 2. Compute bearing
+ double y = Math.sin(long2 - long1) * Math.cos(lat2);
+ double x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(long2 - long1);
+ double brng = Math.atan2(y, x);
+
+ // 3. Compute distance between the 2 points
+ double rotation = Math.toRadians((double)_tcicdWrapper.getInteger(p_rotation) / 10.0) + brng;
+ double lat = Math.asin(Math.sin(lat1) * Math.cos(c) + Math.cos(lat1) * Math.sin(c) * Math.cos(rotation));
+ double long_ = long1 + Math.atan2(Math.sin(rotation) * Math.sin(c)*Math.cos(lat1), Math.cos(c) - Math.sin(lat1) * Math.sin(lat));
+
+ // 4. Normalize
+ // normalise to -180...+180
+ long_ = (long_ + 3 * Math.PI) % (2 * Math.PI) - Math.PI;
+
+ // The out parameter needs to be set on the object level
+ Long rlat = Math.round(Math.toDegrees(lat) * 10000000);
+ Long rlong = Math.round(Math.toDegrees(long_) * 10000000);
+ _tcicdWrapper.setInteger(p_latitude, rlat.intValue());
+ _tcicdWrapper.setInteger(p_longitude, rlong.intValue());
+ } // End of method fx_computePositionFromRotation
+
+ public FloatValue fx_computeRadiusFromCircularArea(FloatValue p_squareMeters) {
+
+ // Initialise the returned value
+ FloatValue radius = _tcicdWrapper.getFloat();
+
+ radius.setFloat((float) Math.sqrt(p_squareMeters.getFloat() / Math.PI));
+
+ return radius;
+ }
+
+ /**
+ * External function to compute timestamp based on current time
+ *
+ * @return Unix-Epoch-Time mod 2^32
+ *
+ * TTCN-3 signature: external function fx_computeGnTimestamp()
+ * return UInt32;
+ */
+ public IntegerValue fx_computeGnTimestamp() {
+
+ IntegerValue timestamp = _tcicdWrapper.setInteger(
+ new BigInteger(
+ 1,
+ ByteHelper.longToByteArray((System.currentTimeMillis() - ITS_REF_TIME) % (long)Math.pow(2,32), Long.SIZE / Byte.SIZE)
+ )
+ );
+
+ return timestamp;
+ }
+
+ /**
+ * @desc Calculate ICMPv6 checksum on pseudo header according RFC 4443 -
+ * Clause 2.3
+ * @param p_sourceAddress
+ * Source address (128 bits),
+ * @param p_destinationAddress
+ * Destination address (128 bits)
+ * @param p_payloadLength
+ * Upper-Layer Packet Length (32 bits)
+ * @param p_payload
+ * Upper-Layer payload
+ * @param p_nextHdr
+ * Next header value (e.g. 0x3a for ICMPv6) (8bits)
+ * @return The checksum value (16bits)
+ * @see RFC 2460 IPv6 Specification
+ *
+ * TTCN-3 signature: external function fx_computeIPv6CheckSum( in
+ * template (value) Ipv6Address p_sourceAddress, in template (value)
+ * Ipv6Address p_destinationAddress, in template (value) integer
+ * p_payloadLength, in template (value) octetstring p_payload, in
+ * template (value) integer p_nextHdr ) return Oct2;
+ *
+ * <pre>
+ * Pseudo header is defined by RFC 2460 - Clause 8.1
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | |
+ * + +
+ * | |
+ * + Source Address +
+ * | |
+ * + +
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | |
+ * + +
+ * | |
+ * + Destination Address +
+ * | |
+ * + +
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Upper-Layer Packet Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | zero | Next Header |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * </pre>
+ */
+ public OctetstringValue fx_computeIPv6CheckSum(
+ final OctetstringValue p_sourceAddress,
+ final OctetstringValue p_destinationAddress,
+ final IntegerValue p_payloadLength,
+ final OctetstringValue p_payload, final IntegerValue p_nextHdr) {
+
+ // Build the pseudo header according RFC 2460 - Clause 8.1
+ ByteArrayOutputStream pseudoheader = new ByteArrayOutputStream();
+ // Source address (128bits)
+ int i = 0;
+ for (; i < p_sourceAddress.getLength(); i++) {
+ pseudoheader.write(p_sourceAddress.getOctet(i));
+ } // End of 'for' loop
+ // Destination address (128bits)
+ for (i = 0; i < p_destinationAddress.getLength(); i++) {
+ pseudoheader.write(p_destinationAddress.getOctet(i));
+ } // End of 'for' loop
+ try {
+ // Upper-Layer Packet Length (32bits)
+ pseudoheader.write(ByteHelper.intToByteArray(_tcicdWrapper.getInteger(p_payloadLength), 4));
+ // Checksum set to 0 (24bits)
+ pseudoheader.write(ByteHelper.intToByteArray(0, 3));
+ // Next header (8bits)
+ pseudoheader.write((byte) _tcicdWrapper.getInteger(p_nextHdr));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ // Add the payload
+ for (i = 0; i < p_payload.getLength(); i++) {
+ pseudoheader.write(p_payload.getOctet(i));
+ } // End of 'for' loop
+
+ i = 0;
+ int length = pseudoheader.size();
+ byte[] buffer = pseudoheader.toByteArray();
+ ByteHelper
+ .dump("ItsExternalFunctionsProvider.fx_computeIPv6CheckSum: pseaudo header",
+ buffer);
+ long sum = 0;
+ while (length > 0) {
+ sum += (buffer[i++] & 0xff) << 8;
+ if ((--length) == 0) {
+ break;
+ }
+ sum += (buffer[i++] & 0xff);
+ --length;
+ }
+ sum = (~((sum & 0xFFFF) + (sum >> 16))) & 0xFFFF;
+
+ // Set the return value
+ OctetstringValue checksum = _tcicdWrapper.getOctetstring();
+ checksum.setLength(2);
+ checksum.setOctet(0, (byte) ((byte) (sum >> 8) & 0xff));
+ checksum.setOctet(1, (byte) (sum & 0x00ff));
+
+ return checksum;
+ }
+
+ public OctetstringValue xf_parseIpv6Address(
+ CharstringValue p_textIpv6Address) {
+
+ byte[] hexIpv6Address = null;
+
+ try {
+ InetAddress ipv6Address = InetAddress.getByName(p_textIpv6Address
+ .getString());
+ hexIpv6Address = ipv6Address.getAddress();
+ } catch (UnknownHostException e) {
+ e.printStackTrace();
+ }
+
+ OctetstringValue result = _tcicdWrapper.getOctetstring();
+ result.setLength(hexIpv6Address.length);
+ for (int i = 0; i < hexIpv6Address.length; i++) {
+ result.setOctet(i, hexIpv6Address[i]);
+ }
+ return result;
+ }
+
+ /**
+ * @desc Produces a 256-bit (32-byte) hash value
+ * @param p_toBeHashedData Data to be used to calculate the hash value
+ * @return The hash value
+ */
+ public OctetstringValue fx_hashWithSha256(final OctetstringValue p_toBeHashedData) {
+
+ byte[] toBeHashedData = new byte[p_toBeHashedData.getLength()];
+ for (int i = 0; i < toBeHashedData.length; i++) {
+ toBeHashedData[i] = (byte) p_toBeHashedData.getOctet(i);
+ } // End 'for' statement
+ byte[] hash = CryptoLib.hashWithSha256(toBeHashedData);
+
+ OctetstringValue result = _tcicdWrapper.getOctetstring();
+ result.setLength(hash.length);
+ for (int i = 0; i < hash.length; i++) {
+ result.setOctet(i, hash[i]);
+ } // End 'for' statement
+ return result;
+ }
+
+ /**
+ * @desc Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signaturee
+ * @param p_toBeSignedData The data to be signed
+ * @param p_privateKey The private key
+ * @return The signature value
+ */
+ public OctetstringValue fx_signWithEcdsaNistp256WithSha256(final OctetstringValue p_toBeSignedData, final OctetstringValue/*IntegerValue*/ p_privateKey) {
+
+ byte[] toBeSignedData = new byte[p_toBeSignedData.getLength()];
+ for (int i = 0; i < toBeSignedData.length; i++) {
+ toBeSignedData[i] = (byte) p_toBeSignedData.getOctet(i);
+ } // End 'for' statement
+ byte[] privateKey = new byte[p_privateKey.getLength()];
+ for (int i = 0; i < privateKey.length; i++) {
+ privateKey[i] = (byte) p_privateKey.getOctet(i);
+ } // End 'for' statement
+ byte[] signed;
+ try {
+ signed = CryptoLib.signWithEcdsaNistp256WithSha256(toBeSignedData, new BigInteger(privateKey));
+ } catch (Exception e) {
+ e.printStackTrace();
+ signed = new byte[] {};
+ }
+
+ OctetstringValue result = _tcicdWrapper.getOctetstring();
+ result.setLength(signed.length);
+ for (int i = 0; i < signed.length; i++) {
+ result.setOctet(i, signed[i]);
+ } // End 'for' statement
+ return result;
+ }
+
+ /**
+ * @desc Verify the signature of the specified data
+ * @param p_toBeVerifiedData The data to be verified
+ * @param p_signature The signature
+ * @param p_ecdsaNistp256PublicKeyX The public key (x coordinate)
+ * @param p_ecdsaNistp256PublicKeyY The public key (y coordinate)
+ * @return true on success, false otherwise
+ */
+ public BooleanValue fx_verifyWithEcdsaNistp256WithSha256(final OctetstringValue p_toBeVerifiedData, final OctetstringValue p_signature, final OctetstringValue p_ecdsaNistp256PublicKeyX, final OctetstringValue p_ecdsaNistp256PublicKeyY) {
+
+ BooleanValue result = _tcicdWrapper.getBoolean();
+ result.setBoolean(false);
+
+ byte[] toBeVerifiedData = new byte[p_toBeVerifiedData.getLength()];
+ for (int i = 0; i < toBeVerifiedData.length; i++) {
+ toBeVerifiedData[i] = (byte) p_toBeVerifiedData.getOctet(i);
+ } // End 'for' statement
+ byte[] ts103097SignatureEncodedAsByteArray = new byte[p_signature.getLength()];
+ for (int i = 0; i < ts103097SignatureEncodedAsByteArray.length; i++) {
+ ts103097SignatureEncodedAsByteArray[i] = (byte) p_signature.getOctet(i);
+ } // End 'for' statement
+ byte[] ecdsaNistp256PublicKeyX = new byte[p_ecdsaNistp256PublicKeyX.getLength()];
+ for (int i = 0; i < ecdsaNistp256PublicKeyX.length; i++) {
+ ecdsaNistp256PublicKeyX[i] = (byte) p_ecdsaNistp256PublicKeyX.getOctet(i);
+ } // End 'for' statement
+ byte[] ecdsaNistp256PublicKeyY = new byte[p_ecdsaNistp256PublicKeyY.getLength()];
+ for (int i = 0; i < ecdsaNistp256PublicKeyY.length; i++) {
+ ecdsaNistp256PublicKeyY[i] = (byte) p_ecdsaNistp256PublicKeyY.getOctet(i);
+ } // End 'for' statement
+ try {
+ boolean ret = CryptoLib.verifyWithEcdsaNistp256WithSha256(toBeVerifiedData, ts103097SignatureEncodedAsByteArray, ecdsaNistp256PublicKeyX, ecdsaNistp256PublicKeyY);
+ result.setBoolean(ret);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return result;
+ }
+
+ /**
+ * @desc Produce a new public/private key pair based on Elliptic Curve Digital Signature Algorithm (ECDSA) algorithm
+ * @param p_privateKey The new private key value
+ * @param p_publicKeyX The new public key value (x coordinate)
+ * @param p_publicKeyX The new public key value (y coordinate)
+ * @return true on success, false otherwise
+ */
+ public BooleanValue fx_generateKeyPair(OctetstringValue/*IntegerValue*/ p_privateKey, OctetstringValue p_publicKeyX, OctetstringValue p_publicKeyY) {
+
+ BooleanValue result = _tcicdWrapper.getBoolean();
+ result.setBoolean(true);
+
+ EcdsaP256KeyPair ecdsaP256KeyPair = CryptoLib.generateKeyPair();
+ byte[] ref = ecdsaP256KeyPair.getPrivateKey().toByteArray();
+ p_privateKey.setLength(ref.length);
+ for (int i = 0; i < p_privateKey.getLength(); i++) {
+ p_privateKey.setOctet(i, ref[i]);
+ } // End 'for' statement
+ ref = ecdsaP256KeyPair.getPublicKeyX();
+ p_publicKeyX.setLength(ref.length);
+ for (int i = 0; i < ref.length; i++) {
+ p_publicKeyX.setOctet(i, ref[i]);
+ } // End 'for' statement
+ ref = ecdsaP256KeyPair.getPublicKeyY();
+ p_publicKeyY.setLength(ref.length);
+ for (int i = 0; i < ref.length; i++) {
+ p_publicKeyY.setOctet(i, ref[i]);
+ } // End 'for' statement
+
+ return result;
+ }
+
+ /**
+ * @desc Check that given polygon doesn't have neither self-intersections nor holes.
+ * @param p_region Polygonal Region
+ * @return true on success, false otherwise
+ */
+ public BooleanValue fx_isValidPolygonalRegion(final RecordOfValue p_region) {
+
+ // Setup arguments
+ ArrayList<WGS84> polygonalArea = new ArrayList<WGS84>();
+ for (int position = 0; position < p_region.getLength(); position++) {
+ RecordValue rv = (RecordValue) p_region.getField(position);
+ polygonalArea.add(
+ new WGS84(
+ _tcicdWrapper.getInteger((IntegerValue)(rv.getField("latitude"))),
+ _tcicdWrapper.getInteger((IntegerValue)(rv.getField("longitude")))
+ ));
+ } // End of 'for' statement
+
+ // Call Geodesic function
+ BooleanValue result = _tcicdWrapper.getBoolean();
+ result.setBoolean(Positioning.getInstance().isValidPolygonArea(polygonalArea));
+
+ return result;
+ }
+
+ public BooleanValue fx_isPolygonalRegionInside(final RecordOfValue p_parent, final RecordOfValue p_region) {
+
+ // Setup arguments
+ ArrayList<WGS84> parentArea = new ArrayList<WGS84>();
+ for (int position = 0; position < p_parent.getLength(); position++) {
+ RecordValue rv = (RecordValue) p_parent.getField(position);
+ parentArea.add(
+ new WGS84(
+ _tcicdWrapper.getInteger((IntegerValue)(rv.getField("latitude"))),
+ _tcicdWrapper.getInteger((IntegerValue)(rv.getField("longitude")))
+ ));
+ } // End of 'for' statement
+ ArrayList<WGS84> regionArea = new ArrayList<WGS84>();
+ for (int position = 0; position < p_region.getLength(); position++) {
+ RecordValue rv = (RecordValue) p_region.getField(position);
+ regionArea.add(
+ new WGS84(
+ _tcicdWrapper.getInteger((IntegerValue)(rv.getField("latitude"))),
+ _tcicdWrapper.getInteger((IntegerValue)(rv.getField("longitude")))
+ ));
+ } // End of 'for' statement
+
+ // Call Geodesic function
+ BooleanValue result = _tcicdWrapper.getBoolean();
+ result.setBoolean(Positioning.getInstance().isPolygonalRegionInside(parentArea, regionArea));
+
+ return result;
+ }
+
+ public BooleanValue fx_isLocationInsideCircularRegion(final RecordValue p_region, final RecordValue p_location) {
+
+ // Setup arguments
+ RecordValue rv = (RecordValue)p_region.getField("center"); // Center
+ WGS84 center = new WGS84(
+ _tcicdWrapper.getInteger((IntegerValue)(rv.getField("latitude"))),
+ _tcicdWrapper.getInteger((IntegerValue)(rv.getField("longitude")))
+ );
+ int radius = _tcicdWrapper.getInteger((IntegerValue)p_region.getField("radius"));
+ WGS84 location = new WGS84( // Location
+ _tcicdWrapper.getInteger((IntegerValue)(p_location.getField("latitude"))),
+ _tcicdWrapper.getInteger((IntegerValue)(p_location.getField("longitude")))
+ );
+
+ // Call Geodesic function
+ BooleanValue result = _tcicdWrapper.getBoolean();
+ result.setBoolean(Positioning.getInstance().isLocationInsideCircularArea(location, center, radius));
+
+ return result;
+ }
+
+ public BooleanValue fx_isLocationInsideRectangularRegion(final RecordOfValue p_region, final RecordValue p_location) {
+
+ // Setup arguments
+ ArrayList< ArrayList<WGS84> > polygonalAreas = new ArrayList< ArrayList<WGS84> >();
+ for (int position = 0; position < p_region.getLength(); position++) {
+ RecordValue rectangleArea = (RecordValue)p_region.getField(position);
+ // Retrieve corners
+ RecordValue rv = (RecordValue)rectangleArea.getField("northwest"); // Upper left corner
+ WGS84 upperLeftCorner = new WGS84(
+ (long)_tcicdWrapper.getInteger((IntegerValue)(rv.getField("latitude"))),
+ (long)_tcicdWrapper.getInteger((IntegerValue)(rv.getField("longitude")))
+ );
+ rv = (RecordValue)rectangleArea.getField("southeast"); // Lower right corner
+ WGS84 lowerRightCorner = new WGS84(
+ (long)_tcicdWrapper.getInteger((IntegerValue)(rv.getField("latitude"))),
+ (long) _tcicdWrapper.getInteger((IntegerValue)(rv.getField("longitude")))
+ );
+ // Build the polygonal area
+ ArrayList<WGS84> rectangularItem = new ArrayList<WGS84>();
+ rectangularItem.add(upperLeftCorner);
+ rectangularItem.add(
+ new WGS84(
+ upperLeftCorner.getLatitude(),
+ lowerRightCorner.getLongitude(),
+ lowerRightCorner.getAltitude()
+ )
+ );
+ rectangularItem.add(lowerRightCorner);
+ rectangularItem.add(
+ new WGS84(
+ lowerRightCorner.getLatitude(),
+ upperLeftCorner.getLongitude(),
+ upperLeftCorner.getAltitude()
+ )
+ );
+
+ polygonalAreas.add(rectangularItem);
+ } // End of 'for' statement
+
+ WGS84 location = new WGS84( // Location
+ _tcicdWrapper.getInteger((IntegerValue)(p_location.getField("latitude"))),
+ _tcicdWrapper.getInteger((IntegerValue)(p_location.getField("longitude")))
+ );
+
+ // Call Geodesic function
+ BooleanValue result = _tcicdWrapper.getBoolean();
+ result.setBoolean(Positioning.getInstance().isLocationInsidePolygonalAreas(location, polygonalAreas));
+
+ return result;
+ }
+
+ public BooleanValue fx_isLocationInsidePolygonalRegion(final RecordOfValue p_region, final RecordValue p_location) {
+
+ // Setup arguments
+ ArrayList<WGS84> polygonalArea = new ArrayList<WGS84>();
+ for (int position = 0; position < p_region.getLength(); position++) {
+ RecordValue rv = (RecordValue) p_region.getField(position);
+ polygonalArea.add(
+ new WGS84(
+ (long)_tcicdWrapper.getInteger((IntegerValue)(rv.getField("latitude"))),
+ (long)_tcicdWrapper.getInteger((IntegerValue)(rv.getField("longitude")))
+ ));
+ } // End of 'for' statement
+ WGS84 location = new WGS84( // Location
+ (long)_tcicdWrapper.getInteger((IntegerValue)(p_location.getField("latitude"))),
+ (long)_tcicdWrapper.getInteger((IntegerValue)(p_location.getField("longitude")))
+ );
+
+ // Call Geodesic function
+ BooleanValue result = _tcicdWrapper.getBoolean();
+ result.setBoolean(Positioning.getInstance().isLocationInsidePolygonalArea(location, polygonalArea));
+
+ return result;
+ }
+
+ public BooleanValue fx_isLocationInsideIdentifiedRegion(final RecordValue p_region, final RecordValue p_location) {
+
+ // Setup arguments
+ int regionDictionary = ((EnumeratedValue) p_region.getField("region_dictionary")).getInt();
+ int regionId = _tcicdWrapper.getInteger((IntegerValue)(p_region.getField("region_identifier")));
+ long localRegion = _tcicdWrapper.getBigInteger((IntegerValue)(p_region.getField("local_region")));
+ WGS84 location = new WGS84( // Location
+ _tcicdWrapper.getInteger((IntegerValue)(p_location.getField("latitude"))),
+ _tcicdWrapper.getInteger((IntegerValue)(p_location.getField("longitude")))
+ );
+
+ // Call Geodesic function
+ BooleanValue result = _tcicdWrapper.getBoolean();
+ result.setBoolean(Positioning.getInstance().isLocationInsideIdentifiedRegion(regionDictionary, regionId, localRegion, location));
+
+ return result;
+ }
+
+ public FloatValue fx_dms2dd(final IntegerValue p_degrees, final IntegerValue p_minutes, final FloatValue p_seconds, final OctetstringValue p_latlon) {
+
+ // Call Geodesic function
+ FloatValue result = _tcicdWrapper.getFloat();
+ DMS location = new DMS( // Location
+ _tcicdWrapper.getInteger(p_degrees),
+ _tcicdWrapper.getInteger(p_minutes),
+ p_seconds.getFloat(),
+ (char)p_latlon.getOctet(0)
+ );
+ result.setFloat((float) location.toDD());
+
+ return result;
+ }
+
+ /**
+ * @desc Load in memory cache the certificates available in the specified directory
+ * @param p_rootDirectory Root directory to access to the certificates identified by the certificate ID
+ * @param p_configId A configuration identifier
+ * @return true on success, false otherwise
+ */
+ public BooleanValue fx_loadCertificates(final CharstringValue p_rootDirectory, final CharstringValue p_configId) {
+
+ BooleanValue result = _tcicdWrapper.getBoolean();
+ result.setBoolean(_certCache.loadCertificates(p_rootDirectory.getString(), p_configId.getString()));
+
+ return result;
+ }
+
+ /**
+ * @desc Unload from memory cache the certificates
+ * @return true on success, false otherwise
+ */
+ public BooleanValue fx_unloadCertificates() {
+
+ BooleanValue result = _tcicdWrapper.getBoolean();
+ result.setBoolean(_certCache.unloadCertificates());
+
+ return result;
+ }
+
+ /**
+ * @desc Read the specified certificate
+ * @param p_certificateId the certificate identifier
+ * @param p_certificate the expected certificate
+ * @return true on success, false otherwise
+ */
+ public BooleanValue fx_readCertificate(final CharstringValue p_certificateId, OctetstringValue p_certificate) {
+
+ BooleanValue result = _tcicdWrapper.getBoolean();
+ ByteArrayOutputStream certificate = new ByteArrayOutputStream();
+ boolean b = _certCache.readCertificate(p_certificateId.getString(), certificate);
+ result.setBoolean(b);
+
+ if(b){
+ byte[] value = certificate.toByteArray();
+ p_certificate.setLength(value.length);
+ if (value.length != 0) {
+ for (int i = 0; i < value.length; i++) {
+ p_certificate.setOctet(i, value[i]);
+ } // End 'for' statement
+ }
+ }else{
+ p_certificate.setLength(0);
+ }
+
+ return result;
+ }
+
+ private static final byte[] ZERO32 = new byte[] {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ /**
+ * @desc Read the specified certificate digest
+ * @param p_certificateId the certificate identifier
+ * @param p_digest the expected certificate digest
+ * @return true on success, false otherwise
+ */
+ public BooleanValue fx_readCertificateDigest(final CharstringValue p_certificateId, OctetstringValue p_digest) {
+
+ BooleanValue result = _tcicdWrapper.getBoolean();
+ ByteArrayOutputStream digest = new ByteArrayOutputStream();
+ boolean b = _certCache.readCertificateDigest(p_certificateId.getString(), digest);
+ result.setBoolean(b);
+
+ p_digest.setLength(8);
+ byte[] value;
+ if(b){
+ value = digest.toByteArray();
+ if (value.length != 8) {
+ value = ZERO32;
+ }
+ }else{
+ value = ZERO32;
+ }
+ for (int i = 0; i < 8; i++) {
+ p_digest.setOctet(i, value[i]);
+ } // End 'for' statement
+ return result;
+ }
+
+ /**
+ * @desc Read the signing private key for the specified certificate
+ * @param p_keysId the keys identifier
+ * @param p_key the signing private key
+ * @return true on success, false otherwise
+ */
+ public BooleanValue fx_readSigningKey(CharstringValue p_keysId, OctetstringValue p_key) {
+
+ BooleanValue result = _tcicdWrapper.getBoolean();
+ ByteArrayOutputStream key = new ByteArrayOutputStream();
+
+ boolean b = _certCache.readSigningKey(p_keysId.getString(), key);
+ result.setBoolean(b);
+
+ p_key.setLength(32);
+
+ byte[] value;
+ if(b){
+ value = key.toByteArray();
+ if(value.length != 32) {
+ value = ZERO32;
+ }
+ }else{
+ value = ZERO32;
+ }
+ for (int i = 0; i < 32; i++) {
+ p_key.setOctet(i, value[i]);
+ }
+ return result;
+ }
+
+ /**
+ * @desc Read the encrypting private key for the specified certificate
+ * @param p_keysId the keys identifier
+ * @param p_key the encrypting private key
+ * @return true on success, false otherwise
+ */
+ public BooleanValue fx_readEncryptingKey(CharstringValue p_keysId, OctetstringValue p_key) {
+
+ BooleanValue result = _tcicdWrapper.getBoolean();
+ ByteArrayOutputStream key = new ByteArrayOutputStream();
+
+ boolean b = _certCache.readEncryptingKey(p_keysId.getString(), key);
+ result.setBoolean(b);
+
+ p_key.setLength(32);
+
+ byte[] value;
+ if(b){
+ value = key.toByteArray();
+ if(value.length != 32) {
+ value = ZERO32;
+ }
+ }else{
+ value = ZERO32;
+ }
+ for (int i = 0; i < 32; i++) {
+ p_key.setOctet(i, value[i]);
+ }
+ return result;
+ }
+
+} // End of class ExternalFunctions
+
/AdapterFramework/javasrc/extfunc/org/etsi/extfunc/its/ItsExternalFunctionsProvider.java
Property changes:
Added: svn:keywords
## -0,0 +1 ##
+URL Author Date Rev Id
\ No newline at end of property
Index: AdapterFramework/javasrc/tool/org/etsi/ttcn/tool/elvior/adapter/PluginAdapter.java
===================================================================
--- AdapterFramework/javasrc/tool/org/etsi/ttcn/tool/elvior/adapter/PluginAdapter.java (revision 2752)
+++ AdapterFramework/javasrc/tool/org/etsi/ttcn/tool/elvior/adapter/PluginAdapter.java (revision 2753)
@@ -18,7 +18,7 @@
import org.etsi.ttcn.codec.core.ITciCDWrapper;
import org.etsi.ttcn.codec.core.TciCDWrapperFactory;
import org.etsi.common.ByteHelper;
-import org.etsi.its.extfunc.ItsExternalFunctionsProvider;
+import org.etsi.extfunc.its.ItsExternalFunctionsProvider;
import org.etsi.ttcn.tool.elvior.codec.TciCDWrapper;
import org.etsi.ttcn.tci.BooleanValue;
import org.etsi.ttcn.tci.CharstringValue;
Index: AdapterFramework/javasrc/tool/org/etsi/ttcn/tool/spirent/xf/ExternalFunctionsPluginProvider.java
===================================================================
--- AdapterFramework/javasrc/tool/org/etsi/ttcn/tool/spirent/xf/ExternalFunctionsPluginProvider.java (revision 2752)
+++ AdapterFramework/javasrc/tool/org/etsi/ttcn/tool/spirent/xf/ExternalFunctionsPluginProvider.java (revision 2753)
@@ -5,7 +5,7 @@
package org.etsi.ttcn.tool.spirent.xf;
import org.etsi.ttcn.codec.core.TciCDWrapperFactory;
-import org.etsi.its.extfunc.ItsExternalFunctionsProvider;
+import org.etsi.extfunc.its.ItsExternalFunctionsProvider;
import org.etsi.ttcn.tool.spirent.codec.TciCDWrapper; // FIXME investigate this
import com.testingtech.ttcn.extension.ExternalFunctionsProvider;
@@ -21,6 +21,14 @@
/**
* Constructor
*
+ */
+ public ExternalFunctionsPluginProvider() {
+
+ }
+
+ /**
+ * Constructor
+ *
* @param rb TTwb runtime reference
*/
public ExternalFunctionsPluginProvider(RB rb) {