DELL
2024-02-21 4982b9614516dde101c3e44c60a612b3bfd8d6fe
iec61850_forFoShanAES_Model/src/org/openmuc/openiec61850/integrationtests/ClientServerITest.java
@@ -1,524 +1,524 @@
package org.openmuc.openiec61850.integrationtests;
import java.io.IOException;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import javax.naming.ConfigurationException;
import org.junit.Assert;
import org.junit.Test;
import org.openmuc.openiec61850.BasicDataAttribute;
import org.openmuc.openiec61850.BdaBoolean;
import org.openmuc.openiec61850.BdaFloat32;
import org.openmuc.openiec61850.BdaInt32;
import org.openmuc.openiec61850.BdaInt32U;
import org.openmuc.openiec61850.BdaQuality;
import org.openmuc.openiec61850.BdaQuality.Validity;
import org.openmuc.openiec61850.BdaReasonForInclusion;
import org.openmuc.openiec61850.BdaTimestamp;
import org.openmuc.openiec61850.BdaVisibleString;
import org.openmuc.openiec61850.ClientAssociation;
import org.openmuc.openiec61850.ClientEventListener;
import org.openmuc.openiec61850.ClientSap;
import org.openmuc.openiec61850.DataSet;
import org.openmuc.openiec61850.Fc;
import org.openmuc.openiec61850.FcModelNode;
import org.openmuc.openiec61850.ModelNode;
import org.openmuc.openiec61850.Report;
import org.openmuc.openiec61850.SclParseException;
import org.openmuc.openiec61850.ServerEventListener;
import org.openmuc.openiec61850.ServerModel;
import org.openmuc.openiec61850.ServerSap;
import org.openmuc.openiec61850.ServiceError;
import org.openmuc.openiec61850.Urcb;
public class ClientServerITest extends Thread implements ServerEventListener, ClientEventListener {
    int port = 54321;
    String host = "127.0.0.1";
    ClientSap clientSap = new ClientSap();
    ServerSap serverSap = null;
    ClientAssociation clientAssociation = null;
    ClientAssociation clientAssociation2 = null;
    ServerModel serversServerModel = null;
    private static int numReports = 0;
    private static int numSuccess = 0;
    private static int numAssociationClosed = 0;
    // Get the Java runtime
    public static Runtime runtime = Runtime.getRuntime();
    @Test
    public void testClientServerCom() throws IOException, ServiceError, ConfigurationException,
            javax.naming.ConfigurationException, SclParseException, InterruptedException {
        clientSap.setTSelRemote(new byte[] { 0, 1 });
        clientSap.setTSelLocal(new byte[] { 0, 0 });
        clientSap.setApTitleCalled(new int[] { 1, 1, 999, 1 });
        BdaTimestamp timestamp;
        BdaVisibleString namePlateVendor;
        // ---------------------------------------------------
        // ------------------1st test server------------------
        runServer("src/test/resources/openiec61850sample01.icd", port);
        System.out.println("IED Server is running");
        // -----------------------------------------------------------
        // Client
        // -----------------------------------------------------------
        System.out.println("Attempting to connect to server " + host + " on port " + port);
        clientAssociation = clientSap.associate(InetAddress.getByName(host), port, null, this);
        // ServerModel serverModel = clientAssociation.retrieveModel();
        ServerModel serverModel = clientAssociation.getModelFromSclFile("src/test/resources/openiec61850sample01.icd");
        getAllBdas(serverModel);
        timestamp = (BdaTimestamp) serverModel.findModelNode("ied1lDevice1/MMXU1.TotW.t", Fc.MX);
        clientAssociation.getDataValues(timestamp);
        namePlateVendor = (BdaVisibleString) serverModel.findModelNode("ied1lDevice1/LLN0.NamPlt.vendor", Fc.DC);
        namePlateVendor.setValue("Fraunhofer ISE".getBytes());
        clientAssociation.setDataValues(namePlateVendor);
        namePlateVendor.setDefault();
        clientAssociation.getDataValues(namePlateVendor);
        Assert.assertEquals("Fraunhofer ISE", new String(namePlateVendor.getValue()));
        // -------------Test DataSets-Start---------------------
        Collection<DataSet> dataSets = serverModel.getDataSets();
        Assert.assertEquals(2, dataSets.size());
        DataSet dataSet1 = serverModel.getDataSet("ied1lDevice1/LLN0.dataset1");
        Assert.assertEquals("ied1lDevice1/LLN0.dataset1", dataSet1.getReferenceStr());
        DataSet dataSet2 = serverModel.getDataSet("ied1lDevice1/LLN0.dataset2");
        Assert.assertEquals("ied1lDevice1/LLN0.dataset2", dataSet2.getReferenceStr());
        for (FcModelNode dataSet2Member : dataSet2) {
            ((BdaInt32) dataSet2Member).setValue(9);
        }
        clientAssociation.setDataSetValues(dataSet2);
        dataSet1 = serverModel.getDataSet(dataSet1.getReferenceStr());
        clientAssociation.getDataSetValues(dataSet1);
        List<FcModelNode> nonPersistentDataSetMembers = new ArrayList<>(2);
        nonPersistentDataSetMembers.add(namePlateVendor);
        nonPersistentDataSetMembers.add(timestamp);
        DataSet nonPersistentDataSet = new DataSet("@nonPersistentDataSet", nonPersistentDataSetMembers);
        clientAssociation.createDataSet(nonPersistentDataSet);
        namePlateVendor.setDefault();
        List<ServiceError> serviceErrors = clientAssociation.getDataSetValues(nonPersistentDataSet);
        for (ServiceError serviceError : serviceErrors) {
            Assert.assertNull(serviceError);
        }
        Assert.assertTrue("Fraunhofer ISE".equals(new String(namePlateVendor.getValue())));
        clientAssociation.deleteDataSet(nonPersistentDataSet);
        serviceErrors = clientAssociation.getDataSetValues(nonPersistentDataSet);
        Assert.assertEquals(2, serviceErrors.size());
        for (ServiceError serviceError : serviceErrors) {
            Assert.assertNotNull(serviceError);
        }
        // -------------Test DataSets-End---------------------
        serverModel.findModelNode("ied1lDevice1/MMXU1.TotW", Fc.MX);
        BdaFloat32 f = (BdaFloat32) serverModel.findModelNode("ied1lDevice1/MMXU1.W.phsA.cVal.mag.f", Fc.MX);
        f.setFloat(3.0f);
        Assert.assertEquals(f.getFloat(), 3.0f, 0.00001);
        clientAssociation.getDataSetValues(dataSet1);
        Assert.assertEquals(f.getFloat(), 0.0f, 0.00001);
        /* Test selecting a controllable Data Object */
        BdaInt32U sboTimeout = (BdaInt32U) serverModel.findModelNode("ied1lDevice1/CSWI1.PosA.sboTimeout", Fc.CF);
        sboTimeout.setValue(2000l);
        BdaVisibleString sbo = (BdaVisibleString) serverModel.findModelNode("ied1lDevice1/CSWI1.PosA.SBO", Fc.CO);
        Assert.assertNotNull(sbo);
        clientAssociation.getDataValues(sbo);
        Assert.assertTrue(sbo.getStringValue().equals("success"));
        clientAssociation.getDataValues(sbo);
        Assert.assertEquals(sbo.getStringValue(), "success");
        /* select with second connection */
        clientAssociation2 = clientSap.associate(InetAddress.getByName(host), port, null, this);
        ServerModel serverModel2 = clientAssociation2.retrieveModel();
        BdaVisibleString sbo2 = (BdaVisibleString) serverModel2.findModelNode("ied1lDevice1/CSWI1.PosA.SBO", Fc.CO);
        clientAssociation2.getDataValues(sbo2);
        Assert.assertEquals(sbo2.getStringValue(), "");
        /* select with second connection after the sboTimeout of 1000ms should have been run out */
        // clientAssociation.close();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        clientAssociation2.getDataValues(sbo2);
        Assert.assertEquals(sbo2.getStringValue(), "success");
        /* select with first connnection after the second was quit */
        clientAssociation.getDataValues(sbo);
        Assert.assertEquals(sbo.getStringValue(), "");
        clientAssociation2.close();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        clientAssociation.getDataValues(sbo);
        Assert.assertEquals(sbo.getStringValue(), "success");
        FcModelNode switchPosAFcDo = (FcModelNode) serverModel.findModelNode("ied1lDevice1/CSWI1.PosA", Fc.CO);
        Assert.assertNotNull(switchPosAFcDo);
        clientAssociation.operate(switchPosAFcDo);
        // -------------Test Reporting-Start-------------------
        Urcb urcb1 = serverModel.getUrcb("ied1lDevice1/LLN0.urcb101");
        Assert.assertNotNull(urcb1);
        Urcb urcb2 = serverModel.getUrcb("ied1lDevice1/LLN0.urcb2");
        Assert.assertNotNull(urcb2);
        clientAssociation.getRcbValues(urcb1);
        clientAssociation.getRcbValues(urcb2);
        BdaBoolean resv = (BdaBoolean) urcb1.getChild("Resv");
        Assert.assertNotNull(resv);
        clientAssociation.getDataValues(resv);
        Assert.assertFalse(resv.getValue());
        clientAssociation.reserveUrcb(urcb1);
        clientAssociation.getDataValues(resv);
        Assert.assertTrue(resv.getValue());
        Assert.assertEquals("urcb1", urcb1.getRptId().getStringValue());
        Assert.assertEquals("ied1lDevice1/LLN0.urcb2", urcb2.getRptId().getStringValue());
        Assert.assertEquals("ied1lDevice1/LLN0$dataset1", urcb1.getDatSet().getStringValue());
        Assert.assertEquals("ied1lDevice1/LLN0$dataset1", urcb2.getDatSet().getStringValue());
        Assert.assertEquals(true, urcb1.getOptFlds().isDataSetName());
        Assert.assertEquals(false, urcb1.getOptFlds().isBufferOverflow());
        Assert.assertEquals(false, urcb1.getOptFlds().isConfigRevision());
        Assert.assertEquals(false, urcb1.getOptFlds().isDataReference());
        Assert.assertEquals(false, urcb1.getOptFlds().isEntryId());
        Assert.assertEquals(true, urcb1.getOptFlds().isReasonForInclusion());
        Assert.assertEquals(true, urcb1.getOptFlds().isReportTimestamp());
        Assert.assertEquals(false, urcb1.getOptFlds().isSegmentation());
        Assert.assertEquals(true, urcb1.getOptFlds().isSequenceNumber());
        Assert.assertEquals(false, urcb2.getOptFlds().isDataSetName());
        Assert.assertEquals(false, urcb2.getOptFlds().isBufferOverflow());
        Assert.assertEquals(false, urcb2.getOptFlds().isConfigRevision());
        Assert.assertEquals(false, urcb2.getOptFlds().isDataReference());
        Assert.assertEquals(false, urcb2.getOptFlds().isEntryId());
        Assert.assertEquals(false, urcb2.getOptFlds().isReasonForInclusion());
        Assert.assertEquals(false, urcb2.getOptFlds().isReportTimestamp());
        Assert.assertEquals(false, urcb2.getOptFlds().isSegmentation());
        Assert.assertEquals(false, urcb2.getOptFlds().isSequenceNumber());
        Assert.assertEquals(50L, urcb1.getBufTm().getValue());
        Assert.assertEquals(true, urcb1.getTrgOps().isDataChange());
        Assert.assertEquals(true, urcb1.getTrgOps().isDataUpdate());
        Assert.assertEquals(true, urcb1.getTrgOps().isGeneralInterrogation());
        Assert.assertEquals(false, urcb1.getTrgOps().isIntegrity());
        Assert.assertEquals(true, urcb1.getTrgOps().isQualityChange());
        Assert.assertEquals(false, urcb2.getTrgOps().isDataChange());
        Assert.assertEquals(false, urcb2.getTrgOps().isDataUpdate());
        Assert.assertEquals(true, urcb2.getTrgOps().isGeneralInterrogation());
        Assert.assertEquals(false, urcb2.getTrgOps().isIntegrity());
        Assert.assertEquals(false, urcb2.getTrgOps().isQualityChange());
        Assert.assertEquals(5000L, urcb1.getIntgPd().getValue());
        Assert.assertEquals(0, urcb1.getSqNum().getValue());
        Assert.assertEquals(0L, urcb1.getConfRev().getValue());
        urcb1.getRptId().setValue("myurcb1");
        urcb1.getTrgOps().setGeneralInterrogation(false);
        urcb1.getTrgOps().setDataUpdate(false);
        urcb1.getTrgOps().setDataChange(false);
        clientAssociation.setRcbValues(urcb1, true, true, true, true, true, true, true, true);
        urcb1.getRptId().setValue("fasdfsadf");
        clientAssociation.getRcbValues(urcb1);
        Assert.assertEquals("myurcb1", urcb1.getRptId().getStringValue());
        clientAssociation.reserveUrcb(urcb1);
        clientAssociation.cancelUrcbReservation(urcb1);
        clientAssociation.enableReporting(urcb1);
        boolean thrown = false;
        try {
            clientAssociation.startGi(urcb1);
        } catch (ServiceError e) {
            thrown = true;
        }
        Assert.assertTrue(thrown);
        urcb1.getTrgOps().setGeneralInterrogation(true);
        urcb1.getTrgOps().setDataChange(true);
        urcb1.getIntgPd().setValue(1000);
        serviceErrors = clientAssociation.setRcbValues(urcb1, false, false, false, false, true, true, false, false);
        Assert.assertNotNull(serviceErrors.get(0));
        clientAssociation.disableReporting(urcb1);
        serviceErrors = clientAssociation.setRcbValues(urcb1, false, false, false, false, true, true, false, false);
        Assert.assertNull(serviceErrors.get(0));
        clientAssociation.enableReporting(urcb1);
        clientAssociation.startGi(urcb1);
        Thread.sleep(4000);
        Assert.assertEquals(2, numReports);
        Assert.assertEquals(2, numSuccess);
        clientAssociation.disableReporting(urcb1);
        urcb1.getTrgOps().setIntegrity(true);
        serviceErrors = clientAssociation.setRcbValues(urcb1, false, false, false, false, true, false, false, false);
        Assert.assertNull(serviceErrors.get(0));
        clientAssociation.enableReporting(urcb1);
        Thread.sleep(6500);
        Assert.assertEquals(8, numReports);
        Assert.assertEquals(8, numSuccess);
        clientAssociation.disableReporting(urcb1);
        // -------------Test Reporting-End---------------------
        clientAssociation.disconnect();
        Thread.sleep(500);
        Assert.assertEquals(2, numAssociationClosed);
        serverSap.stop();
    }
    private void getAllBdas(ServerModel serverModel) throws ServiceError, IOException {
        for (ModelNode ld : serverModel) {
            for (ModelNode ln : ld) {
                getDataRecursive(ln, clientAssociation);
            }
        }
    }
    private void runServer(String sclFilePath, int port) throws SclParseException, IOException {
        List<ServerSap> serverSaps = null;
        serverSaps = ServerSap.getSapsFromSclFile(sclFilePath);
        serverSap = serverSaps.get(0);
        serverSap.setPort(port);
        serverSap.startListening(this);
        serversServerModel = serverSap.getModelCopy();
        start();
    }
    private static void getDataRecursive(ModelNode modelNode, ClientAssociation clientAssociation)
            throws ServiceError, IOException {
        if (modelNode.getChildren() == null) {
            return;
        }
        for (ModelNode childNode : modelNode) {
            FcModelNode fcChildNode = (FcModelNode) childNode;
            if (fcChildNode.getFc() != Fc.CO) {
                System.out.println("calling GetDataValues(" + childNode.getReference() + ")");
                clientAssociation.getDataValues(fcChildNode);
            }
            // clientAssociation.setDataValues(fcChildNode);
            getDataRecursive(childNode, clientAssociation);
        }
    }
    public static int findArray(Byte[] array, Byte[] subArray) {
        return Collections.indexOfSubList(Arrays.asList(array), Arrays.asList(subArray));
    }
    public static String getByteArrayString(byte[] byteArray) {
        StringBuilder builder = new StringBuilder();
        int l = 1;
        for (byte b : byteArray) {
            if ((l != 1) && ((l - 1) % 8 == 0)) {
                builder.append(' ');
            }
            if ((l != 1) && ((l - 1) % 16 == 0)) {
                builder.append('\n');
            }
            l++;
            builder.append("0x");
            String hexString = Integer.toHexString(b & 0xff);
            if (hexString.length() == 1) {
                builder.append(0);
            }
            builder.append(hexString + " ");
        }
        return builder.toString();
    }
    @Override
    public void serverStoppedListening(ServerSap serverSAP) {
        // TODO Auto-generated method stub
    }
    @Override
    public List<ServiceError> write(List<BasicDataAttribute> bdas) {
        System.out.println("DataSource: got write request");
        return null;
    }
    @Override
    public void run() {
        BdaFloat32 totWMag = (BdaFloat32) serversServerModel.findModelNode("ied1lDevice1/MMXU1.TotW.mag.f", Fc.MX);
        BdaQuality q = (BdaQuality) serversServerModel.findModelNode("ied1lDevice1/MMXU1.TotW.q", Fc.MX);
        BdaTimestamp t = (BdaTimestamp) serversServerModel.findModelNode("ied1lDevice1/MMXU1.TotW.t", Fc.MX);
        List<BasicDataAttribute> totWBdas = new ArrayList<>(3);
        totWBdas.add(totWMag);
        totWBdas.add(q);
        totWBdas.add(t);
        float totWMagVal = 0.0f;
        q.setValidity(BdaQuality.Validity.GOOD);
        // for (int i = 0; i < 500000; i++) {
        totWMagVal += 1.0;
        System.out.println("setting totWmag to: " + totWMagVal);
        totWMag.setFloat(totWMagVal);
        t.setCurrentTime();
        if (q.getValidity() == Validity.GOOD) {
            q.setValidity(BdaQuality.Validity.INVALID);
        }
        else {
            q.setValidity(BdaQuality.Validity.GOOD);
        }
        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
        }
        serverSap.setValues(totWBdas);
        // // Run the garbage collector
        // runtime.gc();
        // // Calculate the used memory
        // long memory = runtime.totalMemory() - runtime.freeMemory();
        // System.out.println("Used memory is bytes: " + memory);
        // System.out.println("Used memory is megabytes: " + bytesToMegabytes(memory));
        // try {
        // Thread.sleep(2000);
        // } catch (InterruptedException e) {
        // }
        // }
    }
    private static final long MEGABYTE = 1024L * 1024L;
    public static long bytesToMegabytes(long bytes) {
        return bytes / MEGABYTE;
    }
    @Override
    public void newReport(Report report) {
        System.out.println("got report!");
        numReports++;
        if (numReports == 1) {
            List<BdaReasonForInclusion> reasons = report.getReasonCodes();
            Assert.assertEquals(2, reasons.size());
            Assert.assertTrue(reasons.get(0).isGeneralInterrogation());
            Assert.assertFalse(reasons.get(0).isDataUpdate());
        }
        else if (numReports == 2) {
            List<BdaReasonForInclusion> reasons = report.getReasonCodes();
            Assert.assertEquals(1, reasons.size());
            Assert.assertFalse(reasons.get(0).isGeneralInterrogation());
            Assert.assertTrue(reasons.get(0).isDataChange());
        }
        else if (numReports >= 3) {
            List<BdaReasonForInclusion> reasons = report.getReasonCodes();
            Assert.assertEquals(2, reasons.size());
            Assert.assertTrue(reasons.get(0).isIntegrity());
            Assert.assertTrue(reasons.get(1).isIntegrity());
        }
        numSuccess++;
    }
    @Override
    public void associationClosed(IOException e) {
        System.out.println("Association closed!");
        if (e != null) {
            System.out.println(e.getMessage());
        }
        numAssociationClosed++;
    }
}
package org.openmuc.openiec61850.integrationtests;
import java.io.IOException;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import javax.naming.ConfigurationException;
import org.junit.Assert;
import org.junit.Test;
import org.openmuc.openiec61850.BasicDataAttribute;
import org.openmuc.openiec61850.BdaBoolean;
import org.openmuc.openiec61850.BdaFloat32;
import org.openmuc.openiec61850.BdaInt32;
import org.openmuc.openiec61850.BdaInt32U;
import org.openmuc.openiec61850.BdaQuality;
import org.openmuc.openiec61850.BdaQuality.Validity;
import org.openmuc.openiec61850.BdaReasonForInclusion;
import org.openmuc.openiec61850.BdaTimestamp;
import org.openmuc.openiec61850.BdaVisibleString;
import org.openmuc.openiec61850.ClientAssociation;
import org.openmuc.openiec61850.ClientEventListener;
import org.openmuc.openiec61850.ClientSap;
import org.openmuc.openiec61850.DataSet;
import org.openmuc.openiec61850.Fc;
import org.openmuc.openiec61850.FcModelNode;
import org.openmuc.openiec61850.ModelNode;
import org.openmuc.openiec61850.Report;
import org.openmuc.openiec61850.SclParseException;
import org.openmuc.openiec61850.ServerEventListener;
import org.openmuc.openiec61850.ServerModel;
import org.openmuc.openiec61850.ServerSap;
import org.openmuc.openiec61850.ServiceError;
import org.openmuc.openiec61850.Urcb;
public class ClientServerITest extends Thread implements ServerEventListener, ClientEventListener {
    int port = 54321;
    String host = "127.0.0.1";
    ClientSap clientSap = new ClientSap();
    ServerSap serverSap = null;
    ClientAssociation clientAssociation = null;
    ClientAssociation clientAssociation2 = null;
    ServerModel serversServerModel = null;
    private static int numReports = 0;
    private static int numSuccess = 0;
    private static int numAssociationClosed = 0;
    // Get the Java runtime
    public static Runtime runtime = Runtime.getRuntime();
    @Test
    public void testClientServerCom() throws IOException, ServiceError, ConfigurationException,
            javax.naming.ConfigurationException, SclParseException, InterruptedException {
        clientSap.setTSelRemote(new byte[] { 0, 1 });
        clientSap.setTSelLocal(new byte[] { 0, 0 });
        clientSap.setApTitleCalled(new int[] { 1, 1, 999, 1 });
        BdaTimestamp timestamp;
        BdaVisibleString namePlateVendor;
        // ---------------------------------------------------
        // ------------------1st test server------------------
        runServer("src/test/resources/openiec61850sample01.icd", port);
        System.out.println("IED Server is running");
        // -----------------------------------------------------------
        // Client
        // -----------------------------------------------------------
        System.out.println("Attempting to connect to server " + host + " on port " + port);
        clientAssociation = clientSap.associate(InetAddress.getByName(host), port, null, this);
        // ServerModel serverModel = clientAssociation.retrieveModel();
        ServerModel serverModel = clientAssociation.getModelFromSclFile("src/test/resources/openiec61850sample01.icd");
        getAllBdas(serverModel);
        timestamp = (BdaTimestamp) serverModel.findModelNode("ied1lDevice1/MMXU1.TotW.t", Fc.MX);
        clientAssociation.getDataValues(timestamp);
        namePlateVendor = (BdaVisibleString) serverModel.findModelNode("ied1lDevice1/LLN0.NamPlt.vendor", Fc.DC);
        namePlateVendor.setValue("Fraunhofer ISE".getBytes());
        clientAssociation.setDataValues(namePlateVendor);
        namePlateVendor.setDefault();
        clientAssociation.getDataValues(namePlateVendor);
        Assert.assertEquals("Fraunhofer ISE", new String(namePlateVendor.getValue()));
        // -------------Test DataSets-Start---------------------
        Collection<DataSet> dataSets = serverModel.getDataSets();
        Assert.assertEquals(2, dataSets.size());
        DataSet dataSet1 = serverModel.getDataSet("ied1lDevice1/LLN0.dataset1");
        Assert.assertEquals("ied1lDevice1/LLN0.dataset1", dataSet1.getReferenceStr());
        DataSet dataSet2 = serverModel.getDataSet("ied1lDevice1/LLN0.dataset2");
        Assert.assertEquals("ied1lDevice1/LLN0.dataset2", dataSet2.getReferenceStr());
        for (FcModelNode dataSet2Member : dataSet2) {
            ((BdaInt32) dataSet2Member).setValue(9);
        }
        clientAssociation.setDataSetValues(dataSet2);
        dataSet1 = serverModel.getDataSet(dataSet1.getReferenceStr());
        clientAssociation.getDataSetValues(dataSet1);
        List<FcModelNode> nonPersistentDataSetMembers = new ArrayList<>(2);
        nonPersistentDataSetMembers.add(namePlateVendor);
        nonPersistentDataSetMembers.add(timestamp);
        DataSet nonPersistentDataSet = new DataSet("@nonPersistentDataSet", nonPersistentDataSetMembers);
        clientAssociation.createDataSet(nonPersistentDataSet);
        namePlateVendor.setDefault();
        List<ServiceError> serviceErrors = clientAssociation.getDataSetValues(nonPersistentDataSet);
        for (ServiceError serviceError : serviceErrors) {
            Assert.assertNull(serviceError);
        }
        Assert.assertTrue("Fraunhofer ISE".equals(new String(namePlateVendor.getValue())));
        clientAssociation.deleteDataSet(nonPersistentDataSet);
        serviceErrors = clientAssociation.getDataSetValues(nonPersistentDataSet);
        Assert.assertEquals(2, serviceErrors.size());
        for (ServiceError serviceError : serviceErrors) {
            Assert.assertNotNull(serviceError);
        }
        // -------------Test DataSets-End---------------------
        serverModel.findModelNode("ied1lDevice1/MMXU1.TotW", Fc.MX);
        BdaFloat32 f = (BdaFloat32) serverModel.findModelNode("ied1lDevice1/MMXU1.W.phsA.cVal.mag.f", Fc.MX);
        f.setFloat(3.0f);
        Assert.assertEquals(f.getFloat(), 3.0f, 0.00001);
        clientAssociation.getDataSetValues(dataSet1);
        Assert.assertEquals(f.getFloat(), 0.0f, 0.00001);
        /* Test selecting a controllable Data Object */
        BdaInt32U sboTimeout = (BdaInt32U) serverModel.findModelNode("ied1lDevice1/CSWI1.PosA.sboTimeout", Fc.CF);
        sboTimeout.setValue(2000l);
        BdaVisibleString sbo = (BdaVisibleString) serverModel.findModelNode("ied1lDevice1/CSWI1.PosA.SBO", Fc.CO);
        Assert.assertNotNull(sbo);
        clientAssociation.getDataValues(sbo);
        Assert.assertTrue(sbo.getStringValue().equals("success"));
        clientAssociation.getDataValues(sbo);
        Assert.assertEquals(sbo.getStringValue(), "success");
        /* select with second connection */
        clientAssociation2 = clientSap.associate(InetAddress.getByName(host), port, null, this);
        ServerModel serverModel2 = clientAssociation2.retrieveModel();
        BdaVisibleString sbo2 = (BdaVisibleString) serverModel2.findModelNode("ied1lDevice1/CSWI1.PosA.SBO", Fc.CO);
        clientAssociation2.getDataValues(sbo2);
        Assert.assertEquals(sbo2.getStringValue(), "");
        /* select with second connection after the sboTimeout of 1000ms should have been run out */
        // clientAssociation.close();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        clientAssociation2.getDataValues(sbo2);
        Assert.assertEquals(sbo2.getStringValue(), "success");
        /* select with first connnection after the second was quit */
        clientAssociation.getDataValues(sbo);
        Assert.assertEquals(sbo.getStringValue(), "");
        clientAssociation2.close();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        clientAssociation.getDataValues(sbo);
        Assert.assertEquals(sbo.getStringValue(), "success");
        FcModelNode switchPosAFcDo = (FcModelNode) serverModel.findModelNode("ied1lDevice1/CSWI1.PosA", Fc.CO);
        Assert.assertNotNull(switchPosAFcDo);
        clientAssociation.operate(switchPosAFcDo);
        // -------------Test Reporting-Start-------------------
        Urcb urcb1 = serverModel.getUrcb("ied1lDevice1/LLN0.urcb101");
        Assert.assertNotNull(urcb1);
        Urcb urcb2 = serverModel.getUrcb("ied1lDevice1/LLN0.urcb2");
        Assert.assertNotNull(urcb2);
        clientAssociation.getRcbValues(urcb1);
        clientAssociation.getRcbValues(urcb2);
        BdaBoolean resv = (BdaBoolean) urcb1.getChild("Resv");
        Assert.assertNotNull(resv);
        clientAssociation.getDataValues(resv);
        Assert.assertFalse(resv.getValue());
        clientAssociation.reserveUrcb(urcb1);
        clientAssociation.getDataValues(resv);
        Assert.assertTrue(resv.getValue());
        Assert.assertEquals("urcb1", urcb1.getRptId().getStringValue());
        Assert.assertEquals("ied1lDevice1/LLN0.urcb2", urcb2.getRptId().getStringValue());
        Assert.assertEquals("ied1lDevice1/LLN0$dataset1", urcb1.getDatSet().getStringValue());
        Assert.assertEquals("ied1lDevice1/LLN0$dataset1", urcb2.getDatSet().getStringValue());
        Assert.assertEquals(true, urcb1.getOptFlds().isDataSetName());
        Assert.assertEquals(false, urcb1.getOptFlds().isBufferOverflow());
        Assert.assertEquals(false, urcb1.getOptFlds().isConfigRevision());
        Assert.assertEquals(false, urcb1.getOptFlds().isDataReference());
        Assert.assertEquals(false, urcb1.getOptFlds().isEntryId());
        Assert.assertEquals(true, urcb1.getOptFlds().isReasonForInclusion());
        Assert.assertEquals(true, urcb1.getOptFlds().isReportTimestamp());
        Assert.assertEquals(false, urcb1.getOptFlds().isSegmentation());
        Assert.assertEquals(true, urcb1.getOptFlds().isSequenceNumber());
        Assert.assertEquals(false, urcb2.getOptFlds().isDataSetName());
        Assert.assertEquals(false, urcb2.getOptFlds().isBufferOverflow());
        Assert.assertEquals(false, urcb2.getOptFlds().isConfigRevision());
        Assert.assertEquals(false, urcb2.getOptFlds().isDataReference());
        Assert.assertEquals(false, urcb2.getOptFlds().isEntryId());
        Assert.assertEquals(false, urcb2.getOptFlds().isReasonForInclusion());
        Assert.assertEquals(false, urcb2.getOptFlds().isReportTimestamp());
        Assert.assertEquals(false, urcb2.getOptFlds().isSegmentation());
        Assert.assertEquals(false, urcb2.getOptFlds().isSequenceNumber());
        Assert.assertEquals(50L, urcb1.getBufTm().getValue());
        Assert.assertEquals(true, urcb1.getTrgOps().isDataChange());
        Assert.assertEquals(true, urcb1.getTrgOps().isDataUpdate());
        Assert.assertEquals(true, urcb1.getTrgOps().isGeneralInterrogation());
        Assert.assertEquals(false, urcb1.getTrgOps().isIntegrity());
        Assert.assertEquals(true, urcb1.getTrgOps().isQualityChange());
        Assert.assertEquals(false, urcb2.getTrgOps().isDataChange());
        Assert.assertEquals(false, urcb2.getTrgOps().isDataUpdate());
        Assert.assertEquals(true, urcb2.getTrgOps().isGeneralInterrogation());
        Assert.assertEquals(false, urcb2.getTrgOps().isIntegrity());
        Assert.assertEquals(false, urcb2.getTrgOps().isQualityChange());
        Assert.assertEquals(5000L, urcb1.getIntgPd().getValue());
        Assert.assertEquals(0, urcb1.getSqNum().getValue());
        Assert.assertEquals(0L, urcb1.getConfRev().getValue());
        urcb1.getRptId().setValue("myurcb1");
        urcb1.getTrgOps().setGeneralInterrogation(false);
        urcb1.getTrgOps().setDataUpdate(false);
        urcb1.getTrgOps().setDataChange(false);
        clientAssociation.setRcbValues(urcb1, true, true, true, true, true, true, true, true);
        urcb1.getRptId().setValue("fasdfsadf");
        clientAssociation.getRcbValues(urcb1);
        Assert.assertEquals("myurcb1", urcb1.getRptId().getStringValue());
        clientAssociation.reserveUrcb(urcb1);
        clientAssociation.cancelUrcbReservation(urcb1);
        clientAssociation.enableReporting(urcb1);
        boolean thrown = false;
        try {
            clientAssociation.startGi(urcb1);
        } catch (ServiceError e) {
            thrown = true;
        }
        Assert.assertTrue(thrown);
        urcb1.getTrgOps().setGeneralInterrogation(true);
        urcb1.getTrgOps().setDataChange(true);
        urcb1.getIntgPd().setValue(1000);
        serviceErrors = clientAssociation.setRcbValues(urcb1, false, false, false, false, true, true, false, false);
        Assert.assertNotNull(serviceErrors.get(0));
        clientAssociation.disableReporting(urcb1);
        serviceErrors = clientAssociation.setRcbValues(urcb1, false, false, false, false, true, true, false, false);
        Assert.assertNull(serviceErrors.get(0));
        clientAssociation.enableReporting(urcb1);
        clientAssociation.startGi(urcb1);
        Thread.sleep(4000);
        Assert.assertEquals(2, numReports);
        Assert.assertEquals(2, numSuccess);
        clientAssociation.disableReporting(urcb1);
        urcb1.getTrgOps().setIntegrity(true);
        serviceErrors = clientAssociation.setRcbValues(urcb1, false, false, false, false, true, false, false, false);
        Assert.assertNull(serviceErrors.get(0));
        clientAssociation.enableReporting(urcb1);
        Thread.sleep(6500);
        Assert.assertEquals(8, numReports);
        Assert.assertEquals(8, numSuccess);
        clientAssociation.disableReporting(urcb1);
        // -------------Test Reporting-End---------------------
        clientAssociation.disconnect();
        Thread.sleep(500);
        Assert.assertEquals(2, numAssociationClosed);
        serverSap.stop();
    }
    private void getAllBdas(ServerModel serverModel) throws ServiceError, IOException {
        for (ModelNode ld : serverModel) {
            for (ModelNode ln : ld) {
                getDataRecursive(ln, clientAssociation);
            }
        }
    }
    private void runServer(String sclFilePath, int port) throws SclParseException, IOException {
        List<ServerSap> serverSaps = null;
        serverSaps = ServerSap.getSapsFromSclFile(sclFilePath);
        serverSap = serverSaps.get(0);
        serverSap.setPort(port);
        serverSap.startListening(this);
        serversServerModel = serverSap.getModelCopy();
        start();
    }
    private static void getDataRecursive(ModelNode modelNode, ClientAssociation clientAssociation)
            throws ServiceError, IOException {
        if (modelNode.getChildren() == null) {
            return;
        }
        for (ModelNode childNode : modelNode) {
            FcModelNode fcChildNode = (FcModelNode) childNode;
            if (fcChildNode.getFc() != Fc.CO) {
                System.out.println("calling GetDataValues(" + childNode.getReference() + ")");
                clientAssociation.getDataValues(fcChildNode);
            }
            // clientAssociation.setDataValues(fcChildNode);
            getDataRecursive(childNode, clientAssociation);
        }
    }
    public static int findArray(Byte[] array, Byte[] subArray) {
        return Collections.indexOfSubList(Arrays.asList(array), Arrays.asList(subArray));
    }
    public static String getByteArrayString(byte[] byteArray) {
        StringBuilder builder = new StringBuilder();
        int l = 1;
        for (byte b : byteArray) {
            if ((l != 1) && ((l - 1) % 8 == 0)) {
                builder.append(' ');
            }
            if ((l != 1) && ((l - 1) % 16 == 0)) {
                builder.append('\n');
            }
            l++;
            builder.append("0x");
            String hexString = Integer.toHexString(b & 0xff);
            if (hexString.length() == 1) {
                builder.append(0);
            }
            builder.append(hexString + " ");
        }
        return builder.toString();
    }
    @Override
    public void serverStoppedListening(ServerSap serverSAP) {
        // TODO Auto-generated method stub
    }
    @Override
    public List<ServiceError> write(List<BasicDataAttribute> bdas) {
        System.out.println("DataSource: got write request");
        return null;
    }
    @Override
    public void run() {
        BdaFloat32 totWMag = (BdaFloat32) serversServerModel.findModelNode("ied1lDevice1/MMXU1.TotW.mag.f", Fc.MX);
        BdaQuality q = (BdaQuality) serversServerModel.findModelNode("ied1lDevice1/MMXU1.TotW.q", Fc.MX);
        BdaTimestamp t = (BdaTimestamp) serversServerModel.findModelNode("ied1lDevice1/MMXU1.TotW.t", Fc.MX);
        List<BasicDataAttribute> totWBdas = new ArrayList<>(3);
        totWBdas.add(totWMag);
        totWBdas.add(q);
        totWBdas.add(t);
        float totWMagVal = 0.0f;
        q.setValidity(BdaQuality.Validity.GOOD);
        // for (int i = 0; i < 500000; i++) {
        totWMagVal += 1.0;
        System.out.println("setting totWmag to: " + totWMagVal);
        totWMag.setFloat(totWMagVal);
        t.setCurrentTime();
        if (q.getValidity() == Validity.GOOD) {
            q.setValidity(BdaQuality.Validity.INVALID);
        }
        else {
            q.setValidity(BdaQuality.Validity.GOOD);
        }
        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
        }
        serverSap.setValues(totWBdas);
        // // Run the garbage collector
        // runtime.gc();
        // // Calculate the used memory
        // long memory = runtime.totalMemory() - runtime.freeMemory();
        // System.out.println("Used memory is bytes: " + memory);
        // System.out.println("Used memory is megabytes: " + bytesToMegabytes(memory));
        // try {
        // Thread.sleep(2000);
        // } catch (InterruptedException e) {
        // }
        // }
    }
    private static final long MEGABYTE = 1024L * 1024L;
    public static long bytesToMegabytes(long bytes) {
        return bytes / MEGABYTE;
    }
    @Override
    public void newReport(Report report) {
        System.out.println("got report!");
        numReports++;
        if (numReports == 1) {
            List<BdaReasonForInclusion> reasons = report.getReasonCodes();
            Assert.assertEquals(2, reasons.size());
            Assert.assertTrue(reasons.get(0).isGeneralInterrogation());
            Assert.assertFalse(reasons.get(0).isDataUpdate());
        }
        else if (numReports == 2) {
            List<BdaReasonForInclusion> reasons = report.getReasonCodes();
            Assert.assertEquals(1, reasons.size());
            Assert.assertFalse(reasons.get(0).isGeneralInterrogation());
            Assert.assertTrue(reasons.get(0).isDataChange());
        }
        else if (numReports >= 3) {
            List<BdaReasonForInclusion> reasons = report.getReasonCodes();
            Assert.assertEquals(2, reasons.size());
            Assert.assertTrue(reasons.get(0).isIntegrity());
            Assert.assertTrue(reasons.get(1).isIntegrity());
        }
        numSuccess++;
    }
    @Override
    public void associationClosed(IOException e) {
        System.out.println("Association closed!");
        if (e != null) {
            System.out.println(e.getMessage());
        }
        numAssociationClosed++;
    }
}