connectedAPs = subNetwork.getConnectedAPs();
+
+ for (ConnectedAP connectedAP : connectedAPs) {
+ if (connectedAP.getIedName().equals(iedName)) {
+
+ if (connectedAP.getApName().equals(accessPointName)) {
+
+ if (withOutput)
+ System.out.println("Found connectedAP " + accessPointName + " for IED " + iedName);
+
+ return connectedAP;
+ }
+
+ }
+ }
+
+ }
+ }
+
+ return null;
+ }
}
diff --git a/tools/model_generator/src/com/libiec61850/scl/communication/Address.java b/tools/model_generator/src/com/libiec61850/scl/communication/Address.java
new file mode 100644
index 00000000..6906a2d1
--- /dev/null
+++ b/tools/model_generator/src/com/libiec61850/scl/communication/Address.java
@@ -0,0 +1,42 @@
+package com.libiec61850.scl.communication;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.w3c.dom.Node;
+
+import com.libiec61850.scl.ParserUtils;
+import com.libiec61850.scl.SclParserException;
+
+public class Address
+{
+ Node node;
+
+ private List addressParameters = new LinkedList
();
+
+ public Address(Node addressNode)
+ throws SclParserException
+ {
+ node = addressNode;
+
+ List pNodes = ParserUtils.getChildNodesWithTag(node, "P");
+
+ for (Node pNode : pNodes)
+ addressParameters.add(new P(pNode));
+ }
+
+ public List getAddressParameters()
+ {
+ return addressParameters;
+ }
+
+ public P getAddressParameter(String type)
+ {
+ for (P p : addressParameters) {
+ if (p.getType().equals(type))
+ return p;
+ }
+
+ return null;
+ }
+}
diff --git a/tools/model_generator/src/com/libiec61850/scl/communication/ConnectedAP.java b/tools/model_generator/src/com/libiec61850/scl/communication/ConnectedAP.java
index bfa61d39..26abfbeb 100644
--- a/tools/model_generator/src/com/libiec61850/scl/communication/ConnectedAP.java
+++ b/tools/model_generator/src/com/libiec61850/scl/communication/ConnectedAP.java
@@ -36,6 +36,8 @@ public class ConnectedAP {
private List gses;
private List smvs;
+
+ private Address address = null;
public ConnectedAP(Node node) throws SclParserException {
iedName = ParserUtils.parseAttribute(node, "iedName");
@@ -56,7 +58,12 @@ public class ConnectedAP {
List smvNodes = ParserUtils.getChildNodesWithTag(node, "SMV");
for (Node smvNode : smvNodes)
- smvs.add(new SMV(smvNode));
+ smvs.add(new SMV(smvNode));
+
+ Node addressNode = ParserUtils.getChildNodeWithTag(node, "Address");
+
+ if (addressNode != null)
+ address = new Address(addressNode);
}
public String getIedName() {
@@ -66,6 +73,10 @@ public class ConnectedAP {
public String getApName() {
return apName;
}
+
+ public Address getAddress() {
+ return address;
+ }
public List getGses() {
return gses;
diff --git a/tools/model_generator/src/com/libiec61850/scl/communication/P.java b/tools/model_generator/src/com/libiec61850/scl/communication/P.java
new file mode 100644
index 00000000..32794865
--- /dev/null
+++ b/tools/model_generator/src/com/libiec61850/scl/communication/P.java
@@ -0,0 +1,38 @@
+package com.libiec61850.scl.communication;
+
+import org.w3c.dom.Node;
+
+import com.libiec61850.scl.ParserUtils;
+import com.libiec61850.scl.SclParserException;
+
+public class P
+{
+ private Node node;
+
+ private String type;
+
+ public P(Node pNode) throws SclParserException
+ {
+ node = pNode;
+
+ this.type = ParserUtils.parseAttribute(node, "type");
+
+ if (this.type == null)
+ throw new SclParserException(node, "type is missing in P element!");
+ }
+
+ public String getType()
+ {
+ return type;
+ }
+
+ public String getText()
+ {
+ return node.getTextContent();
+ }
+
+ public void setText(String text)
+ {
+ node.setTextContent(text);
+ }
+}
diff --git a/tools/model_generator/src/com/libiec61850/scl/model/ClientLN.java b/tools/model_generator/src/com/libiec61850/scl/model/ClientLN.java
new file mode 100644
index 00000000..b3275aea
--- /dev/null
+++ b/tools/model_generator/src/com/libiec61850/scl/model/ClientLN.java
@@ -0,0 +1,72 @@
+package com.libiec61850.scl.model;
+
+/*
+ * Copyright 2013-2019 Michael Zillgith, MZ Automation GmbH
+ *
+ * This file is part of libIEC61850.
+ *
+ * libIEC61850 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * libIEC61850 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with libIEC61850. If not, see .
+ *
+ * See COPYING file for the complete license text.
+ */
+
+import org.w3c.dom.Node;
+
+import com.libiec61850.scl.ParserUtils;
+
+public class ClientLN
+{
+ private Node node;
+
+ public ClientLN(Node node)
+ {
+ this.node = node;
+ }
+
+ public String getIedName()
+ {
+ return ParserUtils.parseAttribute(node, "iedName");
+ }
+
+ public String getApRef()
+ {
+ return ParserUtils.parseAttribute(node, "apRef");
+ }
+
+ public String getLdInst()
+ {
+ return ParserUtils.parseAttribute(node, "ldInst");
+ }
+
+ public String getPrefix()
+ {
+ return ParserUtils.parseAttribute(node, "prefix");
+ }
+
+ public String getLnClass()
+ {
+ return ParserUtils.parseAttribute(node, "lnClass");
+ }
+
+ public String getLnInst()
+ {
+ return ParserUtils.parseAttribute(node, "lnInst");
+ }
+
+ public String getDesc()
+ {
+ return ParserUtils.parseAttribute(node, "desc");
+ }
+
+}
diff --git a/tools/model_generator/src/com/libiec61850/scl/model/RptEnabled.java b/tools/model_generator/src/com/libiec61850/scl/model/RptEnabled.java
index 6fb90d35..9282ebf3 100644
--- a/tools/model_generator/src/com/libiec61850/scl/model/RptEnabled.java
+++ b/tools/model_generator/src/com/libiec61850/scl/model/RptEnabled.java
@@ -1,5 +1,8 @@
package com.libiec61850.scl.model;
+import java.util.LinkedList;
+import java.util.List;
+
import org.w3c.dom.Node;
import com.libiec61850.scl.ParserUtils;
@@ -8,6 +11,8 @@ public class RptEnabled {
private int maxInstances = 1;
private String desc = null;
+
+ private List clientLNs = new LinkedList();
public RptEnabled(Node rptEnabledNode) {
this.desc = ParserUtils.parseAttribute(rptEnabledNode, "desc");
@@ -16,6 +21,14 @@ public class RptEnabled {
if (maxString != null) {
maxInstances = new Integer(maxString);
}
+
+ List clientLNNodes = ParserUtils.getChildNodesWithTag(rptEnabledNode, "ClientLN");
+
+ for (Node clientLNNode : clientLNNodes) {
+ ClientLN clientLN = new ClientLN(clientLNNode);
+
+ clientLNs.add(clientLN);
+ }
}
public int getMaxInstances() {
@@ -25,4 +38,9 @@ public class RptEnabled {
public String getDesc() {
return desc;
}
+
+ public List getClientLNs()
+ {
+ return clientLNs;
+ }
}
diff --git a/tools/model_generator/src/com/libiec61850/tools/StaticModelGenerator.java b/tools/model_generator/src/com/libiec61850/tools/StaticModelGenerator.java
index c790ed6a..c8febe3b 100644
--- a/tools/model_generator/src/com/libiec61850/tools/StaticModelGenerator.java
+++ b/tools/model_generator/src/com/libiec61850/tools/StaticModelGenerator.java
@@ -29,17 +29,24 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.PrintStream;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
import java.util.LinkedList;
import java.util.List;
import com.libiec61850.scl.SclParser;
import com.libiec61850.scl.SclParserException;
+import com.libiec61850.scl.communication.Address;
import com.libiec61850.scl.communication.Communication;
import com.libiec61850.scl.communication.ConnectedAP;
import com.libiec61850.scl.communication.GSE;
+import com.libiec61850.scl.communication.P;
import com.libiec61850.scl.communication.PhyComAddress;
import com.libiec61850.scl.communication.SubNetwork;
import com.libiec61850.scl.model.AccessPoint;
+import com.libiec61850.scl.model.ClientLN;
import com.libiec61850.scl.model.DataAttribute;
import com.libiec61850.scl.model.DataModelValue;
import com.libiec61850.scl.model.DataObject;
@@ -53,6 +60,7 @@ import com.libiec61850.scl.model.LogControl;
import com.libiec61850.scl.model.LogicalDevice;
import com.libiec61850.scl.model.LogicalNode;
import com.libiec61850.scl.model.ReportControlBlock;
+import com.libiec61850.scl.model.RptEnabled;
import com.libiec61850.scl.model.SampledValueControl;
import com.libiec61850.scl.model.Server;
import com.libiec61850.scl.model.SettingControl;
@@ -103,6 +111,8 @@ public class StaticModelGenerator {
private String hDefineName;
private String modelPrefix;
private boolean initializeOnce;
+
+ private SclParser sclParser;
public StaticModelGenerator(InputStream stream, String icdFile, PrintStream cOut, PrintStream hOut,
String outputFileName, String iedName, String accessPointName, String modelPrefix,
@@ -131,7 +141,7 @@ public class StaticModelGenerator {
this.logs = new StringBuffer();
this.logVariableNames = new LinkedList();
- SclParser sclParser = new SclParser(stream);
+ sclParser = new SclParser(stream);
this.outputFileName = outputFileName;
this.hDefineName = outputFileName.toUpperCase().replace( '.', '_' ).replace( '-', '_' ) + "_H_";
@@ -1078,6 +1088,24 @@ public class StaticModelGenerator {
gseControlNumber++;
}
}
+
+ private String getIpAddressByIedName(SclParser sclParser, String iedName, String apRef)
+ {
+ ConnectedAP ap = sclParser.getConnectedAP(iedName, apRef);
+
+ if (ap != null) {
+ Address address = ap.getAddress();
+
+ if (address != null) {
+ P ip = address.getAddressParameter("IP");
+
+ if (ip != null)
+ return ip.getText();
+ }
+ }
+
+ return null;
+ }
private void printReportControlBlocks(String lnPrefix, LogicalNode logicalNode) {
List reportControlBlocks = logicalNode.getReportControlBlocks();
@@ -1091,20 +1119,75 @@ public class StaticModelGenerator {
if (rcb.isIndexed()) {
int maxInstances = 1;
+
+ List clientLNs = null;
- if (rcb.getRptEna() != null)
- maxInstances = rcb.getRptEna().getMaxInstances();
+ if (rcb.getRptEna() != null) {
+ RptEnabled rptEna = rcb.getRptEna();
+
+ maxInstances = rptEna.getMaxInstances();
+
+ clientLNs = rptEna.getClientLNs();
+ }
+
for (int i = 0; i < maxInstances; i++) {
String index = String.format("%02d", (i + 1));
System.out.println("print report instance " + index);
+
+ byte[] clientAddress = new byte[17];
+ clientAddress[0] = 0;
+
+ if (clientLNs != null) {
+ try {
+ ClientLN clientLN = clientLNs.get(i);
+
+ if (clientLN != null) {
+
+ String iedName = clientLN.getIedName();
+ String apRef = clientLN.getApRef();
+
+ if ((iedName != null) && (apRef != null)) {
+ String ipAddress = getIpAddressByIedName(sclParser, iedName, apRef);
+
+ try {
+ InetAddress inetAddr = InetAddress.getByName(ipAddress);
+
+ if (inetAddr instanceof Inet4Address) {
+ clientAddress[0] = 4;
+ for (int j = 0; j < 4; j++)
+ clientAddress[j + 1] = inetAddr.getAddress()[j];
+ }
+ else if (inetAddr instanceof Inet6Address) {
+ clientAddress[0] = 6;
+ for (int j = 0; j < 16; j++)
+ clientAddress[j + 1] = inetAddr.getAddress()[j];
+ }
+
+ inetAddr.getAddress();
+ } catch (UnknownHostException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ }
+ }
+ catch (IndexOutOfBoundsException ex) {
+ /* no ClientLN defined for this report instance */
+ }
+ }
+
- printReportControlBlockInstance(lnPrefix, rcb, index, reportNumber, reportsCount);
+ printReportControlBlockInstance(lnPrefix, rcb, index, reportNumber, reportsCount, clientAddress);
reportNumber++;
}
} else {
- printReportControlBlockInstance(lnPrefix, rcb, "", reportNumber, reportsCount);
+ byte[] clientAddress = new byte[17];
+ clientAddress[0] = 0;
+
+ printReportControlBlockInstance(lnPrefix, rcb, "", reportNumber, reportsCount, clientAddress);
reportNumber++;
}
}
@@ -1259,7 +1342,7 @@ public class StaticModelGenerator {
this.logControlBlocks.append(lcbString);
}
- private void printReportControlBlockInstance(String lnPrefix, ReportControlBlock rcb, String index, int reportNumber, int reportsCount)
+ private void printReportControlBlockInstance(String lnPrefix, ReportControlBlock rcb, String index, int reportNumber, int reportsCount, byte[] clientIpAddr)
{
String rcbVariableName = lnPrefix + "_report" + reportNumber;
@@ -1326,9 +1409,19 @@ public class StaticModelGenerator {
rcbString += rcb.getIntegrityPeriod().toString() + ", ";
else
rcbString += "0, ";
+
+ rcbString += "{";
+ for (int i = 0; i < 17; i++) {
+ rcbString += "0x" + Integer.toHexString((int) (clientIpAddr[i] & 0xff));
+ if (i == 16)
+ rcbString += "}, ";
+ else
+ rcbString += ", ";
+ }
+
currentRcbVariableNumber++;
-
+
if (currentRcbVariableNumber < rcbVariableNames.size())
rcbString += "&" + rcbVariableNames.get(currentRcbVariableNumber);
else