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