Commit 4791e3bf authored by garciay's avatar garciay
Browse files

STF507 Week#11: Merge GNSS support from C2C branch

parent cc4c4b7c
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
/**
 *  Factory for GNSS Support implementations. 
 *  Implementations have to register to this factory.  
 * 
 */
package org.etsi.adapter;

/**
 *  Factory for Test Execution Required implementations. 
 *  Implementations have to register to this factory.  
 */
public class GnssSupportFactory {

    /**
     * Registered IGnssSupport implementation
     */
    private static IGnssSupport instance; 

    /**
     * Gets the registered IGnssSupport implementation
     * @return Instance of IGnssSupport implementation registered through setImpl() or null
     * @see    setImpl
     */
    public static IGnssSupport getInstance() {
        return instance;
    }
    
    /**
     * Private constructor (Singleton pattern) 
     */
    private GnssSupportFactory() {
        //empty
    }
    
    /**
     * Sets the implementation instance to be returned by the factory
     * @param  impl    Instance of the implementation to be registered
     */
    public static void setImpl(IGnssSupport impl) {
        instance = impl;
    }
}
+71 −0
Original line number Diff line number Diff line
/*
 * ----------------------------------------------------------------------------
 *  (C) Copyright Testing Technologies, 2001-2015.  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
 *  and ownership notices in full.
 *
 *  See the file COPYRIGHT for details of redistribution and use.
 *
 *  You should have received a copy of the COPYRIGHT file along with
 *  this file; if not, write to the Testing Technologies,
 *  Michaelkirchstr. 17/18, 10179 Berlin, Germany.
 *
 *  TESTING TECHNOLOGIES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
 *  SOFTWARE. IN NO EVENT SHALL TESTING TECHNOLOGIES BE LIABLE FOR ANY
 *  SPECIAL, DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
 *  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 *  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 *  THIS SOFTWARE.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
 *  EITHER EXPRESSED OR IMPLIED, INCLUDING ANY KIND OF IMPLIED OR
 *  EXPRESSED WARRANTY OF NON-INFRINGEMENT OR THE IMPLIED WARRANTIES
 *  OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
 *
 * ----------------------------------------------------------------------------- */
/**
 *  GNSS support interface to be implemented by TE providers.
 */
package org.etsi.adapter;

import org.etsi.ttcn.tri.TriStatus;

/**
 *  Test Execution Required interface to be implemented by TE providers.
 */
public interface IGnssSupport {

  /**
   * Initialize the GNSS support.
   * @return TRI_OK in case of success, false otherwise
   */
  public TriStatus init();
  
  /**
   * Loads a scenario
   * @param id of predefined scenario
   * @return TRUE on success, FALSE otherwise
   */
  public boolean loadScenario(int p_id);
  
  /**
   * Starts a loaded scenario
   * @return TRUE on success, FALSE otherwise
   */
  public boolean startScenario();
  
  /**
   * Stops a started scenario
   * @return TRUE on success, FALSE otherwise
   */
  public boolean stopScenario();
  
  /**
   * Dispose object
   */
  public void dispose();
  
}
+330 −0
Original line number Diff line number Diff line
/*
 * @(#)LEDataInputStream.java
 *
 * Summary: Little-Endian version of DataInputStream.
 *
 * Copyright: (c) 1998-2010 Roedy Green, Canadian Mind Products, http://mindprod.com
 *
 * Licence: This software may be copied and used freely for any purpose but military.
 *          http://mindprod.com/contact/nonmil.html
 *
 * Requires: JDK 1.1+
 *
 * Created with: IntelliJ IDEA IDE.
 *
 * Version History:
 *  1.8 2007-05-24
 */
package org.etsi.its.adapter;

import java.io.DataInput;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * Little-Endian version of DataInputStream.
 * <p/>
 * Very similar to DataInputStream except it reads little-endian instead of
 * big-endian binary data. We can't extend DataInputStream directly since it has
 * only final methods, though DataInputStream itself is not final. This forces
 * us implement LEDataInputStream with a DataInputStream object, and use wrapper
 * methods.
 * 
 * @author Roedy Green, Canadian Mind Products
 * @version 1.8 2007-05-24
 * @since 1998
 */
public final class LEDataInputStream implements DataInput {
    // ------------------------------ CONSTANTS ------------------------------

    /**
     * undisplayed copyright notice.
     * 
     * @noinspection UnusedDeclaration
     */
    private static final String EMBEDDED_COPYRIGHT = "copyright (c) 1999-2010 Roedy Green, Canadian Mind Products, http://mindprod.com";

    // ------------------------------ FIELDS ------------------------------

    /**
     * to get at the big-Endian methods of a basic DataInputStream
     * 
     * @noinspection WeakerAccess
     */
    protected final DataInputStream dis;

    /**
     * to get at the a basic readBytes method.
     * 
     * @noinspection WeakerAccess
     */
    protected final InputStream is;

    /**
     * work array for buffering input.
     * 
     * @noinspection WeakerAccess
     */
    protected final byte[] work;

    // -------------------------- PUBLIC STATIC METHODS
    // --------------------------

    /**
     * Note. This is a STATIC method!
     * 
     * @param in
     *            stream to read UTF chars from (endian irrelevant)
     * 
     * @return string from stream
     * @throws IOException
     *             if read fails.
     */
    public static String readUTF(DataInput in) throws IOException {
        return DataInputStream.readUTF(in);
    }

    // -------------------------- PUBLIC INSTANCE METHODS
    // --------------------------

    /**
     * constructor.
     * 
     * @param in
     *            binary inputstream of little-endian data.
     */
    public LEDataInputStream(InputStream in) {
        this.is = in;
        this.dis = new DataInputStream(in);
        work = new byte[8];
    }

    /**
     * close.
     * 
     * @throws IOException
     *             if close fails.
     */
    public final void close() throws IOException {
        dis.close();
    }

    /**
     * Read bytes. Watch out, read may return fewer bytes than requested.
     * 
     * @param ba
     *            where the bytes go.
     * @param off
     *            offset in buffer, not offset in file.
     * @param len
     *            count of bytes to read.
     * 
     * @return how many bytes read.
     * @throws IOException
     *             if read fails.
     */
    public final int read(byte ba[], int off, int len) throws IOException {
        // For efficiency, we avoid one layer of wrapper
        return is.read(ba, off, len);
    }

    /**
     * read only a one-byte boolean.
     * 
     * @return true or false.
     * @throws IOException
     *             if read fails.
     * @see java.io.DataInput#readBoolean()
     */
    @Override
    public final boolean readBoolean() throws IOException {
        return dis.readBoolean();
    }

    /**
     * read byte.
     * 
     * @return the byte read.
     * @throws IOException
     *             if read fails.
     * @see java.io.DataInput#readByte()
     */
    @Override
    public final byte readByte() throws IOException {
        return dis.readByte();
    }

    /**
     * Read on char. like DataInputStream.readChar except little endian.
     * 
     * @return little endian 16-bit unicode char from the stream.
     * @throws IOException
     *             if read fails.
     */
    @Override
    public final char readChar() throws IOException {
        dis.readFully(work, 0, 2);
        return (char) ((work[1] & 0xff) << 8 | (work[0] & 0xff));
    }

    /**
     * Read a double. like DataInputStream.readDouble except little endian.
     * 
     * @return little endian IEEE double from the datastream.
     * @throws IOException
     */
    @Override
    public final double readDouble() throws IOException {
        return Double.longBitsToDouble(readLong());
    }

    /**
     * Read one float. Like DataInputStream.readFloat except little endian.
     * 
     * @return little endian IEEE float from the datastream.
     * @throws IOException
     *             if read fails.
     */
    @Override
    public final float readFloat() throws IOException {
        return Float.intBitsToFloat(readInt());
    }

    /**
     * Read bytes until the array is filled.
     * 
     * @see java.io.DataInput#readFully(byte[])
     */
    @Override
    public final void readFully(byte ba[]) throws IOException {
        dis.readFully(ba, 0, ba.length);
    }

    /**
     * Read bytes until the count is satisfied.
     * 
     * @throws IOException
     *             if read fails.
     * @see java.io.DataInput#readFully(byte[],int,int)
     */
    @Override
    public final void readFully(byte ba[], int off, int len) throws IOException {
        dis.readFully(ba, off, len);
    }

    /**
     * Read an int, 32-bits. Like DataInputStream.readInt except little endian.
     * 
     * @return little-endian binary int from the datastream
     * @throws IOException
     *             if read fails.
     */
    @Override
    public final int readInt() throws IOException {
        dis.readFully(work, 0, 4);
        return (work[3]) << 24 | (work[2] & 0xff) << 16 | (work[1] & 0xff) << 8
                | (work[0] & 0xff);
    }

    /**
     * Read a line.
     * 
     * @return a rough approximation of the 8-bit stream as a 16-bit unicode
     *         string
     * @throws IOException
     * @noinspection deprecation
     * @deprecated This method does not properly convert bytes to characters.
     *             Use a Reader instead with a little-endian encoding.
     */
    @Deprecated
    @Override
    public final String readLine() throws IOException {
        return dis.readLine();
    }

    /**
     * read a long, 64-bits. Like DataInputStream.readLong except little endian.
     * 
     * @return little-endian binary long from the datastream.
     * @throws IOException
     */
    @Override
    public final long readLong() throws IOException {
        dis.readFully(work, 0, 8);
        return (long) (work[7]) << 56 |
        /* long cast needed or shift done modulo 32 */
        (long) (work[6] & 0xff) << 48 | (long) (work[5] & 0xff) << 40
                | (long) (work[4] & 0xff) << 32 | (long) (work[3] & 0xff) << 24
                | (long) (work[2] & 0xff) << 16 | (long) (work[1] & 0xff) << 8
                | work[0] & 0xff;
    }

    /**
     * Read short, 16-bits. Like DataInputStream.readShort except little endian.
     * 
     * @return little endian binary short from stream.
     * @throws IOException
     *             if read fails.
     */
    @Override
    public final short readShort() throws IOException {
        dis.readFully(work, 0, 2);
        return (short) ((work[1] & 0xff) << 8 | (work[0] & 0xff));
    }

    /**
     * Read UTF counted string.
     * 
     * @return String read.
     */
    @Override
    public final String readUTF() throws IOException {
        return dis.readUTF();
    }

    /**
     * Read an unsigned byte. Note: returns an int, even though says Byte
     * (non-Javadoc)
     * 
     * @throws IOException
     *             if read fails.
     * @see java.io.DataInput#readUnsignedByte()
     */
    @Override
    public final int readUnsignedByte() throws IOException {
        return dis.readUnsignedByte();
    }

    /**
     * Read an unsigned short, 16 bits. Like DataInputStream.readUnsignedShort
     * except little endian. Note, returns int even though it reads a short.
     * 
     * @return little-endian int from the stream.
     * @throws IOException
     *             if read fails.
     */
    @Override
    public final int readUnsignedShort() throws IOException {
        dis.readFully(work, 0, 2);
        return ((work[1] & 0xff) << 8 | (work[0] & 0xff));
    }

    /**
     * Skip over bytes in the stream. See the general contract of the
     * <code>skipBytes</code> method of <code>DataInput</code>.
     * <p/>
     * Bytes for this operation are read from the contained input stream.
     * 
     * @param n
     *            the number of bytes to be skipped.
     * 
     * @return the actual number of bytes skipped.
     * @throws IOException
     *             if an I/O error occurs.
     */
    @Override
    public final int skipBytes(int n) throws IOException {
        return dis.skipBytes(n);
    }
}
 No newline at end of file
+99 −2
Original line number Diff line number Diff line
@@ -8,8 +8,13 @@
 */
package org.etsi.its.adapter.ports;

import org.etsi.adapter.GnssSupportFactory;
import org.etsi.adapter.IGnssSupport;
import org.etsi.adapter.TERFactory;
import org.etsi.common.ByteHelper;
import org.etsi.its.adapter.Management;
import org.etsi.ttcn.tci.BooleanValue;
import org.etsi.ttcn.tri.TriStatus;

/** This class implements behaviour for Adapter controller port
 *
@@ -20,10 +25,12 @@ public class AdapterControlPort extends AdapterPort implements IPort, IObservabl
    /* AdapterControl Primitives */
    private static final byte AcGnPrimitive = 0;
    private static final byte AcGn6Primitive = 1;
    private static final byte AcGnssPrimitive = 2;
    
    /* AdapterControl Response */
    private static final byte AcGnResponse = 0;
    //private static final byte AcGn6Response = 1;
    private static final byte AcGnssResponse = 2;

    /* GN Commands */
    private static final byte AcStartBeaconing = 0;
@@ -40,9 +47,18 @@ public class AdapterControlPort extends AdapterPort implements IPort, IObservabl
    protected static final byte AcGnResponseFailure = 0;
    protected static final byte AcLongPosVector = 6;

    /* SCENARIO commands */
    private static final byte AcLoadScenario = 0x70;
    private static final byte AcStartScenario = 0x71;
    private static final byte AcStopScenario = 0x72;

    protected static final byte AcTrue = 0x01;
    protected static final byte AcFalse = 0x01;
    protected static final byte AcFalse = 0x00;
    
    private static final String GNSS_SCENARIO_SUPPORT = "GnssScenarioSupport";
    private IGnssSupport GNSS;
    private boolean isScenarioStarted = false;
    private boolean gnssScenarioSupport;
    /**
     * Constructor
     * @param   portName        Name of the port
@@ -50,6 +66,15 @@ public class AdapterControlPort extends AdapterPort implements IPort, IObservabl
     */
    public AdapterControlPort(final String portName, final String componentName) {
        super(portName, componentName);
        try {
            gnssScenarioSupport = ((BooleanValue) TERFactory.getInstance().getTaParameter(GNSS_SCENARIO_SUPPORT)).getBoolean();
        }
        catch (Throwable th) {
            gnssScenarioSupport = false;
        }
        if (gnssScenarioSupport) {
            GNSS = GnssSupportFactory.getInstance();
        }
    }

    @Override
@@ -120,6 +145,30 @@ public class AdapterControlPort extends AdapterPort implements IPort, IObservabl
                    }         
                    */
                    break;
                case AcGnssPrimitive:
                    if (gnssScenarioSupport) {
                        byte[] data = ByteHelper.extract(message, 2, message.length - 2);
                        switch (message[1]) {
                            case AcLoadScenario:
                                LoadScenario(data[0]);
                                break;
                            case AcStartScenario:
                                StartScenario();
                                break;
                            case AcStopScenario:
                                StopScenario();
                                break;
                        }
                    }
                    else {
                        TERFactory.getInstance().getTriStatus(TriStatus.TRI_OK, "AcGnssPrimitive cannot be handled as the "
                                + GNSS_SCENARIO_SUPPORT + " is set to false!");
                        result = false;
                    }
                    break;
                default:
                    ByteHelper.dump("Unsupported AC primitive", message);
                    break;
            } // End of 'switch' statement

            return result;
@@ -167,9 +216,57 @@ public class AdapterControlPort extends AdapterPort implements IPort, IObservabl
            notifyObservers(new PortEvent(response, getPortName(), getComponentName()));
        }

    private void LoadScenario(final int scenario) {
        new Thread(new Runnable() {
            @Override
            public void run() { 
                boolean result = GNSS.loadScenario(scenario);
                byte[] response = {(byte)AcGnssResponse, (byte)(result?AcTrue:AcFalse)};
                
                setChanged();
                notifyObservers(new PortEvent(response, getPortName(), getComponentName()));
            }
        }).start();
    }

    private void StartScenario() {
        new Thread(new Runnable() {
            @Override
            public void run() { 
                isScenarioStarted = GNSS.startScenario();
                byte[] response = {(byte)AcGnssResponse, (byte)(isScenarioStarted?AcTrue:AcFalse)};
                
                setChanged();
                notifyObservers(new PortEvent(response, getPortName(), getComponentName()));
            }
        }).start();
    }

    private void StopScenario() {
        new Thread(new Runnable() {
            @Override
            public void run() { 
                boolean result = GNSS.stopScenario();
                isScenarioStarted = !result;
                byte[] response = {(byte)AcGnssResponse, (byte)(isScenarioStarted?AcFalse:AcTrue)};
                
                setChanged();
                notifyObservers(new PortEvent(response, getPortName(), getComponentName()));
            }
        }).start();
    }

    @Override
    public void dispose() {
        //empty
        if (gnssScenarioSupport) {
            if (GNSS!=null) {
                if (isScenarioStarted) {
                    GNSS.stopScenario();
                }
                GNSS.dispose();
            }
            GNSS = null;
        }
    }

} // End of class AdapterControlPort
+64 −0
Original line number Diff line number Diff line
package org.etsi.ttcn.codec.its.adapter;

import org.etsi.ttcn.tci.Type;
import org.etsi.ttcn.tci.UnionValue;
import org.etsi.ttcn.codec.generic.Union;
import org.etsi.ttcn.codec.MainCodec;
import org.etsi.ttcn.codec.CodecBuffer;
import org.etsi.ttcn.common.ByteHelper;

public class AcGnssPrimitive extends Union {

    public AcGnssPrimitive(MainCodec mainCodec) {
        super(mainCodec);
    }

    @Override
    protected void preDecode(CodecBuffer buf, Type decodingHypothesis) {

        // Read message id (AcGnssPrimitive)
        if(0x00 != (0x00FF & buf.readBytes(1)[0])) {
            return;
        }

        // Read primitive id
        int primitiveId = 0x00FF & buf.readBytes(1)[0];
        String primitive = "";

        switch(primitiveId) {
        case 0x70:
            primitive = "loadScenario";
            break;
        case 0x71:
            primitive = "startScenario";
            break;
        case 0x72:
            primitive = "stopScenario";
            break;
        }

        mainCodec.setHint(decodingHypothesis.getName(), primitive);
    }

    @Override
    protected void preEncode(CodecBuffer buf, UnionValue uv) {
        String variant = uv.getPresentVariantName();
        int primitiveId = -1;

        // Append AcDenmPrimitive message id
        buf.appendBytes(ByteHelper.intToByteArray(2, 1));

        // Append primitive id
        if(variant.equals("loadScenario")) {
            primitiveId = 0x70;
            mainCodec.setHint("ScenarioLen", "16");
        }
        else if(variant.equals("startScenario")) {
            primitiveId = 0x71;
        }
        else if(variant.equals("stopScenario")) {
            primitiveId = 0x72;
        }
        buf.appendBytes(ByteHelper.intToByteArray(primitiveId, 1));
    }
}
Loading