From 4982b9614516dde101c3e44c60a612b3bfd8d6fe Mon Sep 17 00:00:00 2001
From: DELL <DELL@WIN-3EOIPEE9ML1>
Date: 星期三, 21 二月 2024 16:26:06 +0800
Subject: [PATCH] 新增IEDScout调试工具功能

---
 iec61850_forFoShanAES_Model/src/org/openmuc/openiec61850/ServerSap.java |  838 +++++++++++++++++++++++++++++-----------------------------
 1 files changed, 419 insertions(+), 419 deletions(-)

diff --git a/iec61850_forFoShanAES_Model/src/org/openmuc/openiec61850/ServerSap.java b/iec61850_forFoShanAES_Model/src/org/openmuc/openiec61850/ServerSap.java
index 31d7d81..6809a65 100644
--- a/iec61850_forFoShanAES_Model/src/org/openmuc/openiec61850/ServerSap.java
+++ b/iec61850_forFoShanAES_Model/src/org/openmuc/openiec61850/ServerSap.java
@@ -1,419 +1,419 @@
-/*
- * Copyright 2011-17 Fraunhofer ISE, energy & meteo Systems GmbH and other contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-package org.openmuc.openiec61850;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.InetAddress;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Timer;
-
-import javax.net.ServerSocketFactory;
-
-import org.openmuc.josistack.AcseAssociation;
-import org.openmuc.josistack.ServerAcseSap;
-
-/**
- * The <code>ServerSap</code> class represents the IEC 61850 service access point for server applications. It
- * corresponds to the AccessPoint defined in the ICD/SCL file. A server application that is to listen for client
- * connections should first get an instance of <code>ServerSap</code> using the static function
- * ServerSap.getSapsFromSclFile(). Next all the necessary configuration parameters can be set. Finally the
- * <code>startListening</code> function is called to listen for client associations. Changing properties of a ServerSap
- * after starting to listen is not recommended and has unknown effects.
- */
-public final class ServerSap {
-
-    static final int MINIMUM_MMS_PDU_SIZE = 64;
-    private static final int MAXIMUM_MMS_PDU_SIZE = 65000;
-
-    private int proposedMaxMmsPduSize = 65000;
-    private int proposedMaxServOutstandingCalling = 5;
-    private int proposedMaxServOutstandingCalled = 5;
-    private int proposedDataStructureNestingLevel = 10;
-    byte[] servicesSupportedCalled = new byte[] { (byte) 0xee, 0x1c, 0, 0, 0x04, 0x08, 0, 0, 0x79, (byte) 0xef, 0x18 };
-    byte[] cbbBitString = { (byte) (0xfb), 0x00 };
-    private int maxAssociations = 100;
-
-    ServerEventListener serverEventListener;
-    private ServerAcseSap acseSap;
-
-    private final String name;
-    private int port = 102;
-    private int backlog = 0;
-    private InetAddress bindAddr = null;
-    private ServerSocketFactory serverSocketFactory = null;
-
-    Timer timer;
-
-    List<ServerAssociation> associations = new ArrayList<>();
-    boolean listening = false;
-
-    public final ServerModel serverModel;//2021-5-6 for common model use
-
-    public static List<ServerSap> getSapsFromSclFile(String sclFilePath) throws SclParseException {
-        SclParser sclParserObject = new SclParser();
-        sclParserObject.parse(sclFilePath);
-        return sclParserObject.getServerSaps();
-    }
-
-    public static List<ServerSap> getSapsFromSclFile(InputStream sclFileStream) throws SclParseException {
-        SclParser sclParserObject = new SclParser();
-        sclParserObject.parse(sclFileStream);
-        return sclParserObject.getServerSaps();
-    }
-
-    /**
-     * Creates a ServerSap.
-     * 
-     * @param port
-     *            local port to listen on for new connections
-     * @param backlog
-     *            The maximum queue length for incoming connection indications (a request to connect) is set to the
-     *            backlog parameter. If a connection indication arrives when the queue is full, the connection is
-     *            refused. Set to 0 or less for the default value.
-     * @param bindAddr
-     *            local IP address to bind to, pass null to bind to all
-     * @param serverSocketFactory
-     *            the factory class to generate the ServerSocket. Could be used to create SSLServerSockets. null =
-     *            default
-     * 
-     */
-    ServerSap(int port, int backlog, InetAddress bindAddr, ServerModel serverModel, String name,
-            ServerSocketFactory serverSocketFactory) {
-        this.port = port;
-        this.backlog = backlog;
-        this.bindAddr = bindAddr;
-        this.serverSocketFactory = serverSocketFactory;
-        this.name = name;
-        this.serverModel = serverModel;
-    }
-
-    /**
-     * Sets local port to listen on for new connections.
-     * 
-     * @param port
-     *            local port to listen on for new connections
-     */
-    public void setPort(int port) {
-        this.port = port;
-    }
-
-    public int getPort() {
-        return port;
-    }
-
-    /**
-     * Sets the maximum queue length for incoming connection indications (a request to connect) is set to the backlog
-     * parameter. If a connection indication arrives when the queue is full, the connection is refused. Set to 0 or less
-     * for the default value.
-     * 
-     * @param backlog
-     *            the maximum queue length for incoming connections.
-     */
-    public void setBacklog(int backlog) {
-        this.backlog = backlog;
-    }
-
-    public int getBacklog() {
-        return backlog;
-    }
-
-    /**
-     * Sets the local IP address to bind to, pass null to bind to all
-     * 
-     * @param bindAddr
-     *            the local IP address to bind to
-     */
-    public void setBindAddress(InetAddress bindAddr) {
-        this.bindAddr = bindAddr;
-    }
-
-    public InetAddress getBindAddress() {
-        return bindAddr;
-    }
-
-    /**
-     * Returns the name of the ServerSap / AccessPoint as specified in the SCL file.
-     * 
-     * @return the name.
-     */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * Sets the factory class to generate the ServerSocket. The ServerSocketFactory could be used to create
-     * SSLServerSockets. Set to <code>null</code> to use <code>ServerSocketFactory.getDefault()</code>.
-     * 
-     * @param serverSocketFactory
-     *            the factory class to generate the ServerSocket.
-     */
-    public void setServerSocketFactory(ServerSocketFactory serverSocketFactory) {
-        this.serverSocketFactory = serverSocketFactory;
-    }
-
-    /**
-     * Sets the maximum MMS PDU size in bytes that the server will support. If the client requires the use of a smaller
-     * maximum MMS PDU size, then the smaller size will be accepted by the server. The default size is 65000.
-     * 
-     * @param size
-     *            cannot be less than 64. The upper limit is 65000 so that segmentation at the lower transport layer is
-     *            avoided. The Transport Layer's maximum PDU size is 65531.
-     */
-    public void setMaxMmsPduSize(int size) {
-        if (size >= MINIMUM_MMS_PDU_SIZE && size <= MAXIMUM_MMS_PDU_SIZE) {
-            proposedMaxMmsPduSize = size;
-        }
-        else {
-            throw new IllegalArgumentException("maximum size is out of bound");
-        }
-    }
-
-    /**
-     * Gets the maximum MMS PDU size.
-     * 
-     * @return the maximum MMS PDU size.
-     */
-    public int getMaxMmsPduSize() {
-        return proposedMaxMmsPduSize;
-    }
-
-    /**
-     * Set the maximum number of associations that are allowed in parallel by the server.
-     * 
-     * @param maxAssociations
-     *            the number of associations allowed (default is 100)
-     */
-    public void setMaxAssociations(int maxAssociations) {
-        this.maxAssociations = maxAssociations;
-    }
-
-    /**
-     * Sets the message fragment timeout. This is the timeout that the socket timeout is set to after the first byte of
-     * a message has been received. If such a timeout is thrown, the association/socket is closed.
-     * 
-     * @param timeout
-     *            the message fragment timeout in milliseconds. The default is 60000.
-     */
-    public void setMessageFragmentTimeout(int timeout) {
-        acseSap.serverTSap.setMessageFragmentTimeout(timeout);
-    }
-
-    /**
-     * Sets the ProposedMaxServOutstandingCalling parameter. The given parameter has no affect on the functionality of
-     * this server.
-     * 
-     * @param maxCalling
-     *            the ProposedMaxServOutstandingCalling parameter. The default is 5.
-     */
-    public void setProposedMaxServOutstandingCalling(int maxCalling) {
-        proposedMaxServOutstandingCalling = maxCalling;
-    }
-
-    /**
-     * Gets the ProposedMaxServOutstandingCalling parameter.
-     * 
-     * @return the ProposedMaxServOutstandingCalling parameter.
-     */
-    public int getProposedMaxServOutstandingCalling() {
-        return proposedMaxServOutstandingCalling;
-    }
-
-    /**
-     * Sets the ProposedMaxServOutstandingCalled parameter.The given parameter has no affect on the functionality of
-     * this server.
-     * 
-     * @param maxCalled
-     *            the ProposedMaxServOutstandingCalled parameter. The default is 5.
-     */
-    public void setProposedMaxServOutstandingCalled(int maxCalled) {
-        proposedMaxServOutstandingCalled = maxCalled;
-    }
-
-    /**
-     * Gets the ProposedMaxServOutstandingCalled parameter.
-     * 
-     * @return the ProposedMaxServOutstandingCalled parameter.
-     */
-    public int getProposedMaxServOutstandingCalled() {
-        return proposedMaxServOutstandingCalled;
-    }
-
-    /**
-     * Sets the ProposedDataStructureNestingLevel parameter. The given parameter has no affect on the functionality of
-     * this server.runServer
-     * 
-     * @param nestingLevel
-     *            the ProposedDataStructureNestingLevel parameter. The default is 10.
-     */
-    public void setProposedDataStructureNestingLevel(int nestingLevel) {
-        proposedDataStructureNestingLevel = nestingLevel;
-    }
-
-    /**
-     * Gets the ProposedDataStructureNestingLevel parameter.
-     * 
-     * @return the ProposedDataStructureNestingLevel parameter.
-     */
-    public int getProposedDataStructureNestingLevel() {
-        return proposedDataStructureNestingLevel;
-    }
-
-    /**
-     * Sets the SevicesSupportedCalled parameter. The given parameter has no affect on the functionality of this server.
-     * 
-     * @param services
-     *            the ServicesSupportedCalled parameter
-     */
-    public void setServicesSupportedCalled(byte[] services) {
-        if (services.length != 11) {
-            throw new IllegalArgumentException("The services parameter needs to be of lenth 11");
-        }
-        servicesSupportedCalled = services;
-    }
-
-    /**
-     * Gets the ServicesSupportedCalled parameter.
-     * 
-     * @return the ServicesSupportedCalled parameter.
-     */
-    public byte[] getServicesSupportedCalled() {
-        return servicesSupportedCalled;
-    }
-
-    /**
-     * Creates a server socket waiting on the configured port for incoming association requests.
-     * 
-     * @param serverEventListener
-     *            the listener that is notified of incoming writes and when the server stopped listening for new
-     *            connections.
-     * @throws IOException
-     *             if an error occurs binding to the port.
-     */
-    public void startListening(ServerEventListener serverEventListener) throws IOException {
-        timer = new Timer();
-        if (serverSocketFactory == null) {
-            serverSocketFactory = ServerSocketFactory.getDefault();
-        }
-        acseSap = new ServerAcseSap(port, backlog, bindAddr, new AcseListener(this), serverSocketFactory);
-        acseSap.serverTSap.setMaxConnections(maxAssociations);
-        this.serverEventListener = serverEventListener;
-        listening = true;
-        acseSap.startListening();
-    }
-
-    /**
-     * Stops listening for new connections and closes all existing connections/associations.
-     */
-    public void stop() {
-        acseSap.stopListening();
-        synchronized (associations) {
-            listening = false;
-            for (ServerAssociation association : associations) {
-                association.close();
-            }
-            associations.clear();
-        }
-        timer.cancel();
-        timer.purge();
-    }
-
-    void connectionIndication(AcseAssociation acseAssociation, ByteBuffer psdu) {
-
-        ServerAssociation association;
-        synchronized (associations) {
-            if (listening) {
-                association = new ServerAssociation(this);
-                associations.add(association);
-            }
-            else {
-                acseAssociation.close();
-                return;
-            }
-        }
-
-        try {
-            association.handleNewAssociation(acseAssociation, psdu);
-        } catch (Exception e) {
-            // Association closed because of an unexpected exception.
-        }
-
-        association.close();
-        synchronized (associations) {
-            associations.remove(association);
-        }
-    }
-
-    void serverStoppedListeningIndication(IOException e) {
-        if (serverEventListener != null) {
-            serverEventListener.serverStoppedListening(this);
-        }
-    }
-
-    public ServerModel getModelCopy() {
-        return serverModel.copy();
-    }
-
-    public void setValues(List<BasicDataAttribute> bdas) {
-        synchronized (serverModel) {
-            for (BasicDataAttribute bda : bdas) {
-                // if (bda.getFunctionalConstraint() != FunctionalConstraint.ST) {
-                // logger.debug("fc:" + bda.getFunctionalConstraint());
-                // throw new IllegalArgumentException(
-                // "One can only set values of BDAs with Functional Constraint ST(status)");
-                // }
-
-                BasicDataAttribute bdaMirror = bda.mirror;
-
-                if (bdaMirror.dchg && bdaMirror.chgRcbs.size() != 0 && !bda.equals(bdaMirror)) {
-                    bdaMirror.setValueFrom(bda);
-                    synchronized (bdaMirror.chgRcbs) {
-                        for (Urcb urcb : bdaMirror.chgRcbs) {
-                            if (bdaMirror.dupd && urcb.getTrgOps().isDataUpdate()) {
-                                urcb.report(bdaMirror, true, false, true);
-                            }
-                            else {
-                                urcb.report(bdaMirror, true, false, false);
-                            }
-                        }
-                    }
-                }
-                else if (bdaMirror.dupd && bdaMirror.dupdRcbs.size() != 0) {
-                    bdaMirror.setValueFrom(bda);
-                    synchronized (bdaMirror.dupdRcbs) {
-                        for (Urcb urcb : bdaMirror.dupdRcbs) {
-                            urcb.report(bdaMirror, false, false, true);
-                        }
-                    }
-                }
-                else if (bdaMirror.qchg && bdaMirror.chgRcbs.size() != 0 && !bda.equals(bdaMirror)) {
-                    bdaMirror.setValueFrom(bda);
-                    synchronized (bdaMirror.chgRcbs) {
-                        for (Urcb urcb : bdaMirror.chgRcbs) {
-                            urcb.report(bdaMirror, false, true, false);
-                        }
-                    }
-                }
-                else {
-                    bdaMirror.setValueFrom(bda);
-                }
-            }
-        }
-    }
-}
+/*
+ * Copyright 2011-17 Fraunhofer ISE, energy & meteo Systems GmbH and other contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.openmuc.openiec61850;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Timer;
+
+import javax.net.ServerSocketFactory;
+
+import org.openmuc.josistack.AcseAssociation;
+import org.openmuc.josistack.ServerAcseSap;
+
+/**
+ * The <code>ServerSap</code> class represents the IEC 61850 service access point for server applications. It
+ * corresponds to the AccessPoint defined in the ICD/SCL file. A server application that is to listen for client
+ * connections should first get an instance of <code>ServerSap</code> using the static function
+ * ServerSap.getSapsFromSclFile(). Next all the necessary configuration parameters can be set. Finally the
+ * <code>startListening</code> function is called to listen for client associations. Changing properties of a ServerSap
+ * after starting to listen is not recommended and has unknown effects.
+ */
+public final class ServerSap {
+
+    static final int MINIMUM_MMS_PDU_SIZE = 64;
+    private static final int MAXIMUM_MMS_PDU_SIZE = 65000;
+
+    private int proposedMaxMmsPduSize = 65000;
+    private int proposedMaxServOutstandingCalling = 5;
+    private int proposedMaxServOutstandingCalled = 5;
+    private int proposedDataStructureNestingLevel = 10;
+    byte[] servicesSupportedCalled = new byte[] { (byte) 0xee, 0x1c, 0, 0, 0x04, 0x08, 0, 0, 0x79, (byte) 0xef, 0x18 };
+    byte[] cbbBitString = { (byte) (0xfb), 0x00 };
+    private int maxAssociations = 100;
+
+    ServerEventListener serverEventListener;
+    private ServerAcseSap acseSap;
+
+    private final String name;
+    private int port = 102;
+    private int backlog = 0;
+    private InetAddress bindAddr = null;
+    private ServerSocketFactory serverSocketFactory = null;
+
+    Timer timer;
+
+    List<ServerAssociation> associations = new ArrayList<>();
+    boolean listening = false;
+
+    public final ServerModel serverModel;
+
+    public static List<ServerSap> getSapsFromSclFile(String sclFilePath) throws SclParseException {
+        SclParser sclParserObject = new SclParser();
+        sclParserObject.parse(sclFilePath);
+        return sclParserObject.getServerSaps();
+    }
+
+    public static List<ServerSap> getSapsFromSclFile(InputStream sclFileStream) throws SclParseException {
+        SclParser sclParserObject = new SclParser();
+        sclParserObject.parse(sclFileStream);
+        return sclParserObject.getServerSaps();
+    }
+
+    /**
+     * Creates a ServerSap.
+     * 
+     * @param port
+     *            local port to listen on for new connections
+     * @param backlog
+     *            The maximum queue length for incoming connection indications (a request to connect) is set to the
+     *            backlog parameter. If a connection indication arrives when the queue is full, the connection is
+     *            refused. Set to 0 or less for the default value.
+     * @param bindAddr
+     *            local IP address to bind to, pass null to bind to all
+     * @param serverSocketFactory
+     *            the factory class to generate the ServerSocket. Could be used to create SSLServerSockets. null =
+     *            default
+     * 
+     */
+    ServerSap(int port, int backlog, InetAddress bindAddr, ServerModel serverModel, String name,
+            ServerSocketFactory serverSocketFactory) {
+        this.port = port;
+        this.backlog = backlog;
+        this.bindAddr = bindAddr;
+        this.serverSocketFactory = serverSocketFactory;
+        this.name = name;
+        this.serverModel = serverModel;
+    }
+
+    /**
+     * Sets local port to listen on for new connections.
+     * 
+     * @param port
+     *            local port to listen on for new connections
+     */
+    public void setPort(int port) {
+        this.port = port;
+    }
+
+    public int getPort() {
+        return port;
+    }
+
+    /**
+     * Sets the maximum queue length for incoming connection indications (a request to connect) is set to the backlog
+     * parameter. If a connection indication arrives when the queue is full, the connection is refused. Set to 0 or less
+     * for the default value.
+     * 
+     * @param backlog
+     *            the maximum queue length for incoming connections.
+     */
+    public void setBacklog(int backlog) {
+        this.backlog = backlog;
+    }
+
+    public int getBacklog() {
+        return backlog;
+    }
+
+    /**
+     * Sets the local IP address to bind to, pass null to bind to all
+     * 
+     * @param bindAddr
+     *            the local IP address to bind to
+     */
+    public void setBindAddress(InetAddress bindAddr) {
+        this.bindAddr = bindAddr;
+    }
+
+    public InetAddress getBindAddress() {
+        return bindAddr;
+    }
+
+    /**
+     * Returns the name of the ServerSap / AccessPoint as specified in the SCL file.
+     * 
+     * @return the name.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Sets the factory class to generate the ServerSocket. The ServerSocketFactory could be used to create
+     * SSLServerSockets. Set to <code>null</code> to use <code>ServerSocketFactory.getDefault()</code>.
+     * 
+     * @param serverSocketFactory
+     *            the factory class to generate the ServerSocket.
+     */
+    public void setServerSocketFactory(ServerSocketFactory serverSocketFactory) {
+        this.serverSocketFactory = serverSocketFactory;
+    }
+
+    /**
+     * Sets the maximum MMS PDU size in bytes that the server will support. If the client requires the use of a smaller
+     * maximum MMS PDU size, then the smaller size will be accepted by the server. The default size is 65000.
+     * 
+     * @param size
+     *            cannot be less than 64. The upper limit is 65000 so that segmentation at the lower transport layer is
+     *            avoided. The Transport Layer's maximum PDU size is 65531.
+     */
+    public void setMaxMmsPduSize(int size) {
+        if (size >= MINIMUM_MMS_PDU_SIZE && size <= MAXIMUM_MMS_PDU_SIZE) {
+            proposedMaxMmsPduSize = size;
+        }
+        else {
+            throw new IllegalArgumentException("maximum size is out of bound");
+        }
+    }
+
+    /**
+     * Gets the maximum MMS PDU size.
+     * 
+     * @return the maximum MMS PDU size.
+     */
+    public int getMaxMmsPduSize() {
+        return proposedMaxMmsPduSize;
+    }
+
+    /**
+     * Set the maximum number of associations that are allowed in parallel by the server.
+     * 
+     * @param maxAssociations
+     *            the number of associations allowed (default is 100)
+     */
+    public void setMaxAssociations(int maxAssociations) {
+        this.maxAssociations = maxAssociations;
+    }
+
+    /**
+     * Sets the message fragment timeout. This is the timeout that the socket timeout is set to after the first byte of
+     * a message has been received. If such a timeout is thrown, the association/socket is closed.
+     * 
+     * @param timeout
+     *            the message fragment timeout in milliseconds. The default is 60000.
+     */
+    public void setMessageFragmentTimeout(int timeout) {
+        acseSap.serverTSap.setMessageFragmentTimeout(timeout);
+    }
+
+    /**
+     * Sets the ProposedMaxServOutstandingCalling parameter. The given parameter has no affect on the functionality of
+     * this server.
+     * 
+     * @param maxCalling
+     *            the ProposedMaxServOutstandingCalling parameter. The default is 5.
+     */
+    public void setProposedMaxServOutstandingCalling(int maxCalling) {
+        proposedMaxServOutstandingCalling = maxCalling;
+    }
+
+    /**
+     * Gets the ProposedMaxServOutstandingCalling parameter.
+     * 
+     * @return the ProposedMaxServOutstandingCalling parameter.
+     */
+    public int getProposedMaxServOutstandingCalling() {
+        return proposedMaxServOutstandingCalling;
+    }
+
+    /**
+     * Sets the ProposedMaxServOutstandingCalled parameter.The given parameter has no affect on the functionality of
+     * this server.
+     * 
+     * @param maxCalled
+     *            the ProposedMaxServOutstandingCalled parameter. The default is 5.
+     */
+    public void setProposedMaxServOutstandingCalled(int maxCalled) {
+        proposedMaxServOutstandingCalled = maxCalled;
+    }
+
+    /**
+     * Gets the ProposedMaxServOutstandingCalled parameter.
+     * 
+     * @return the ProposedMaxServOutstandingCalled parameter.
+     */
+    public int getProposedMaxServOutstandingCalled() {
+        return proposedMaxServOutstandingCalled;
+    }
+
+    /**
+     * Sets the ProposedDataStructureNestingLevel parameter. The given parameter has no affect on the functionality of
+     * this server.runServer
+     * 
+     * @param nestingLevel
+     *            the ProposedDataStructureNestingLevel parameter. The default is 10.
+     */
+    public void setProposedDataStructureNestingLevel(int nestingLevel) {
+        proposedDataStructureNestingLevel = nestingLevel;
+    }
+
+    /**
+     * Gets the ProposedDataStructureNestingLevel parameter.
+     * 
+     * @return the ProposedDataStructureNestingLevel parameter.
+     */
+    public int getProposedDataStructureNestingLevel() {
+        return proposedDataStructureNestingLevel;
+    }
+
+    /**
+     * Sets the SevicesSupportedCalled parameter. The given parameter has no affect on the functionality of this server.
+     * 
+     * @param services
+     *            the ServicesSupportedCalled parameter
+     */
+    public void setServicesSupportedCalled(byte[] services) {
+        if (services.length != 11) {
+            throw new IllegalArgumentException("The services parameter needs to be of lenth 11");
+        }
+        servicesSupportedCalled = services;
+    }
+
+    /**
+     * Gets the ServicesSupportedCalled parameter.
+     * 
+     * @return the ServicesSupportedCalled parameter.
+     */
+    public byte[] getServicesSupportedCalled() {
+        return servicesSupportedCalled;
+    }
+
+    /**
+     * Creates a server socket waiting on the configured port for incoming association requests.
+     * 
+     * @param serverEventListener
+     *            the listener that is notified of incoming writes and when the server stopped listening for new
+     *            connections.
+     * @throws IOException
+     *             if an error occurs binding to the port.
+     */
+    public void startListening(ServerEventListener serverEventListener) throws IOException {
+        timer = new Timer();
+        if (serverSocketFactory == null) {
+            serverSocketFactory = ServerSocketFactory.getDefault();
+        }
+        acseSap = new ServerAcseSap(port, backlog, bindAddr, new AcseListener(this), serverSocketFactory);
+        acseSap.serverTSap.setMaxConnections(maxAssociations);
+        this.serverEventListener = serverEventListener;
+        listening = true;
+        acseSap.startListening();
+    }
+
+    /**
+     * Stops listening for new connections and closes all existing connections/associations.
+     */
+    public void stop() {
+        acseSap.stopListening();
+        synchronized (associations) {
+            listening = false;
+            for (ServerAssociation association : associations) {
+                association.close();
+            }
+            associations.clear();
+        }
+        timer.cancel();
+        timer.purge();
+    }
+
+    void connectionIndication(AcseAssociation acseAssociation, ByteBuffer psdu) {
+
+        ServerAssociation association;
+        synchronized (associations) {
+            if (listening) {
+                association = new ServerAssociation(this);
+                associations.add(association);
+            }
+            else {
+                acseAssociation.close();
+                return;
+            }
+        }
+
+        try {
+            association.handleNewAssociation(acseAssociation, psdu);
+        } catch (Exception e) {
+            // Association closed because of an unexpected exception.
+        }
+
+        association.close();
+        synchronized (associations) {
+            associations.remove(association);
+        }
+    }
+
+    void serverStoppedListeningIndication(IOException e) {
+        if (serverEventListener != null) {
+            serverEventListener.serverStoppedListening(this);
+        }
+    }
+
+    public ServerModel getModelCopy() {
+        return serverModel.copy();
+    }
+
+    public void setValues(List<BasicDataAttribute> bdas) {
+        synchronized (serverModel) {
+            for (BasicDataAttribute bda : bdas) {
+                // if (bda.getFunctionalConstraint() != FunctionalConstraint.ST) {
+                // logger.debug("fc:" + bda.getFunctionalConstraint());
+                // throw new IllegalArgumentException(
+                // "One can only set values of BDAs with Functional Constraint ST(status)");
+                // }
+
+                BasicDataAttribute bdaMirror = bda.mirror;
+
+                if (bdaMirror.dchg && bdaMirror.chgRcbs.size() != 0 && !bda.equals(bdaMirror)) {
+                    bdaMirror.setValueFrom(bda);
+                    synchronized (bdaMirror.chgRcbs) {
+                        for (Urcb urcb : bdaMirror.chgRcbs) {
+                            if (bdaMirror.dupd && urcb.getTrgOps().isDataUpdate()) {
+                                urcb.report(bdaMirror, true, false, true);
+                            }
+                            else {
+                                urcb.report(bdaMirror, true, false, false);
+                            }
+                        }
+                    }
+                }
+                else if (bdaMirror.dupd && bdaMirror.dupdRcbs.size() != 0) {
+                    bdaMirror.setValueFrom(bda);
+                    synchronized (bdaMirror.dupdRcbs) {
+                        for (Urcb urcb : bdaMirror.dupdRcbs) {
+                            urcb.report(bdaMirror, false, false, true);
+                        }
+                    }
+                }
+                else if (bdaMirror.qchg && bdaMirror.chgRcbs.size() != 0 && !bda.equals(bdaMirror)) {
+                    bdaMirror.setValueFrom(bda);
+                    synchronized (bdaMirror.chgRcbs) {
+                        for (Urcb urcb : bdaMirror.chgRcbs) {
+                            urcb.report(bdaMirror, false, true, false);
+                        }
+                    }
+                }
+                else {
+                    bdaMirror.setValueFrom(bda);
+                }
+            }
+        }
+    }
+}

--
Gitblit v1.9.1