From 366fa7a1bb8af7aef4dc8f5c519cdc23506bb1dd Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Mon, 14 Dec 2015 19:02:02 +0100 Subject: [PATCH 1/6] - fixed bug for TC sDsN12: non-persitent dataset not allowed for BRCB --- src/iec61850/server/mms_mapping/reporting.c | 24 +++++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/iec61850/server/mms_mapping/reporting.c b/src/iec61850/server/mms_mapping/reporting.c index ab3d67e5..4b5061b4 100644 --- a/src/iec61850/server/mms_mapping/reporting.c +++ b/src/iec61850/server/mms_mapping/reporting.c @@ -503,16 +503,24 @@ updateReportDataset(MmsMapping* mapping, ReportControl* rc, MmsValue* newDatSet, if (dataSet == NULL) { + /* check if association specific data set is requested */ + + if (dataSetName[0] == '@') { - if (connection != NULL) { - MmsNamedVariableList mmsVariableList - = MmsServerConnection_getNamedVariableList(connection, dataSetName + 1); - if (mmsVariableList != NULL) - dataSet = MmsMapping_createDataSetByNamedVariableList(mapping, mmsVariableList); + if (rc->buffered == false) { /* for buffered report non-permanent datasets are not allowed */ + if (connection != NULL) { + MmsNamedVariableList mmsVariableList + = MmsServerConnection_getNamedVariableList(connection, dataSetName + 1); + + if (mmsVariableList != NULL) + dataSet = MmsMapping_createDataSetByNamedVariableList(mapping, mmsVariableList); + } } + } + /* check for VMD specific data set */ else if (dataSetName[0] == '/') { MmsNamedVariableList mmsVariableList = MmsDevice_getNamedVariableListWithName(mapping->mmsDevice, dataSetName + 1); @@ -1315,8 +1323,10 @@ Reporting_RCBWriteAccessHandler(MmsMapping* self, ReportControl* rc, char* eleme if (strcmp(elementName, "GI") == 0) { if ((rc->enabled) && (rc->clientConnection == connection)) { - if (MmsValue_getBoolean(value)) - rc->gi = true; + if (MmsValue_getBoolean(value)) { + if (rc->triggerOps & TRG_OPT_GI) + rc->gi = true; + } retVal = DATA_ACCESS_ERROR_SUCCESS; goto exit_function; From ed8a73873d858b6888a8dc6244ebf7a83a4847c7 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Mon, 14 Dec 2015 19:06:26 +0100 Subject: [PATCH 2/6] - fixed bug for TC sBr25: Purge buffer when RptID is changes --- src/iec61850/server/mms_mapping/reporting.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/iec61850/server/mms_mapping/reporting.c b/src/iec61850/server/mms_mapping/reporting.c index 4b5061b4..7303b489 100644 --- a/src/iec61850/server/mms_mapping/reporting.c +++ b/src/iec61850/server/mms_mapping/reporting.c @@ -1458,6 +1458,9 @@ Reporting_RCBWriteAccessHandler(MmsMapping* self, ReportControl* rc, char* eleme else if (strcmp(elementName, "RptID") == 0) { MmsValue* rptId = ReportControl_getRCBValue(rc, elementName); + if (rc->buffered) + purgeBuf(rc); + if (strlen(MmsValue_toString(value)) == 0) updateWithDefaultRptId(rc, rptId); else From 0a82e09b92938392180f332875a48d3c565d43f9 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Mon, 14 Dec 2015 19:14:50 +0100 Subject: [PATCH 3/6] - fixed bug for TC sBr21: set BufOvfl when entryID is not set --- src/iec61850/server/mms_mapping/reporting.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/iec61850/server/mms_mapping/reporting.c b/src/iec61850/server/mms_mapping/reporting.c index 7303b489..c72a3b2b 100644 --- a/src/iec61850/server/mms_mapping/reporting.c +++ b/src/iec61850/server/mms_mapping/reporting.c @@ -1301,7 +1301,10 @@ Reporting_RCBWriteAccessHandler(MmsMapping* self, ReportControl* rc, char* eleme printf("IED_SERVER: Deactivate report for client %s\n", MmsServerConnection_getClientAddress(connection)); - if (rc->buffered == false) { + if (rc->buffered) { + rc->reportBuffer->isOverflow = true; + } + else { GLOBAL_FREEMEM(rc->inclusionFlags); rc->inclusionFlags = NULL; @@ -1428,11 +1431,13 @@ Reporting_RCBWriteAccessHandler(MmsMapping* self, ReportControl* rc, char* eleme retVal = DATA_ACCESS_ERROR_OBJECT_VALUE_INVALID; goto exit_function; } + + rc->reportBuffer->isOverflow = false; } else { rc->reportBuffer->nextToTransmit = rc->reportBuffer->oldestReport; - rc->isResync = false; rc->reportBuffer->isOverflow = true; + rc->isResync = false; } MmsValue* entryID = ReportControl_getRCBValue(rc, elementName); From 26d188ab4d09b43151e9e45ec39a777983a6c363 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Mon, 14 Dec 2015 19:42:57 +0100 Subject: [PATCH 4/6] - fixed bug with access to "Owner" attribute of BRCBs when resvTms not available --- src/iec61850/server/mms_mapping/reporting.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/iec61850/server/mms_mapping/reporting.c b/src/iec61850/server/mms_mapping/reporting.c index c72a3b2b..ee606180 100644 --- a/src/iec61850/server/mms_mapping/reporting.c +++ b/src/iec61850/server/mms_mapping/reporting.c @@ -220,10 +220,15 @@ ReportControl_getRCBValue(ReportControl* rc, char* elementName) return MmsValue_getElement(rc->rcbValues, 11); else if (strcmp(elementName, "TimeofEntry") == 0) return MmsValue_getElement(rc->rcbValues, 12); +#if (CONFIG_IEC61850_BRCB_WITH_RESVTMS == 1) else if (strcmp(elementName, "ResvTms") == 0) return MmsValue_getElement(rc->rcbValues, 13); else if (strcmp(elementName, "Owner") == 0) return MmsValue_getElement(rc->rcbValues, 14); +#else + else if (strcmp(elementName, "Owner") == 0) + return MmsValue_getElement(rc->rcbValues, 13); +#endif } else { if (strcmp(elementName, "RptID") == 0) return MmsValue_getElement(rc->rcbValues, 0); @@ -1001,7 +1006,7 @@ createBufferedReportControlBlock(ReportControlBlock* reportControlBlock, namedVariable->type = MMS_OCTET_STRING; namedVariable->typeSpec.octetString = -64; rcb->typeSpec.structure.elements[currentIndex] = namedVariable; - mmsValue->value.structure.components[currentIndex] = MmsValue_newOctetString(0, 4); /* size 4 is enough to store client IPv4 address */ + mmsValue->value.structure.components[currentIndex] = MmsValue_newOctetString(0, 128); /* size 4 is enough to store client IPv4 address */ reportControl->rcbValues = mmsValue; From daa0a1e95867b554b43b942baf1591b8749d5f49 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Mon, 14 Dec 2015 20:05:17 +0100 Subject: [PATCH 5/6] - GoCB DatSet and GoID are now readonly by stack_config.h --- config/stack_config.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/config/stack_config.h b/config/stack_config.h index b5ece377..405a5a1a 100644 --- a/config/stack_config.h +++ b/config/stack_config.h @@ -102,9 +102,14 @@ /* The number of GOOSE retransmissions after an event */ #define CONFIG_GOOSE_EVENT_RETRANSMISSION_COUNT 2 -/* Define if GOOSE control block elements are writable (1) or read-only (0) */ -#define CONFIG_GOOSE_GOID_WRITABLE 1 -#define CONFIG_GOOSE_DATSET_WRITABLE 1 +/* Define if GOOSE control block elements are writable (1) or read-only (0) + * + * WARNING: To be compliant with the IEC 61850-8-1 standard all GoCB elements + * but GoEna have to be read-only! + * + * */ +#define CONFIG_GOOSE_GOID_WRITABLE 0 +#define CONFIG_GOOSE_DATSET_WRITABLE 0 #define CONFIG_GOOSE_CONFREV_WRITABLE 0 #define CONFIG_GOOSE_NDSCOM_WRITABLE 0 #define CONFIG_GOOSE_DSTADDRESS_WRITABLE 0 From 9e626d58b8576f3dc746e661346d64ee261b1610 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Fri, 25 Dec 2015 18:33:24 +0100 Subject: [PATCH 6/6] - added java based modelviewer tool --- .../server_example_dynamic.c | 5 +- src/iec61850/server/mms_mapping/reporting.c | 7 +- src/mms/iso_mms/server/mms_file_service.c | 12 +- tools/model_generator/build-modelviewer.sh | 12 + tools/model_generator/manifest-modelviewer.mf | 2 + .../src/com/libiec61850/scl/SclParser.java | 36 ++- .../com/libiec61850/scl/model/DataObject.java | 9 +- .../com/libiec61850/scl/types/SclType.java | 2 +- .../scl/types/TypeDeclarations.java | 6 + .../tools/DynamicModelGenerator.java | 2 +- .../com/libiec61850/tools/ModelViewer.java | 254 ++++++++++++++++++ .../tools/StaticModelGenerator.java | 2 +- 12 files changed, 324 insertions(+), 25 deletions(-) create mode 100755 tools/model_generator/build-modelviewer.sh create mode 100644 tools/model_generator/manifest-modelviewer.mf create mode 100644 tools/model_generator/src/com/libiec61850/tools/ModelViewer.java diff --git a/examples/server_example_dynamic/server_example_dynamic.c b/examples/server_example_dynamic/server_example_dynamic.c index 1d01c40a..2bab1f05 100644 --- a/examples/server_example_dynamic/server_example_dynamic.c +++ b/examples/server_example_dynamic/server_example_dynamic.c @@ -83,9 +83,8 @@ int main(int argc, char** argv) { while (running) { IedServer_lockDataModel(iedServer); - MmsValue_setFloat(temperatureValue->mmsValue, val); - MmsValue_setUtcTimeMs(temperatureTimestamp->mmsValue, Hal_getTimeInMs()); - IedServer_updateAttributeValue(iedServer, temperatureValue, temperatureValue->mmsValue); + IedServer_updateUTCTimeAttributeValue(iedServer, temperatureTimestamp, Hal_getTimeInMs()) + IedServer_updateFloatAttributeValue(iedServer, temperatureValue, val); IedServer_unlockDataModel(iedServer); diff --git a/src/iec61850/server/mms_mapping/reporting.c b/src/iec61850/server/mms_mapping/reporting.c index ee606180..2ce1a3ff 100644 --- a/src/iec61850/server/mms_mapping/reporting.c +++ b/src/iec61850/server/mms_mapping/reporting.c @@ -57,7 +57,7 @@ ReportBuffer_create(void) self->memoryBlockSize = CONFIG_REPORTING_DEFAULT_REPORT_BUFFER_SIZE; self->memoryBlock = (uint8_t*) GLOBAL_MALLOC(self->memoryBlockSize); self->reportsCount = 0; - self->isOverflow = false; + self->isOverflow = true; return self; } @@ -1266,8 +1266,10 @@ Reporting_RCBWriteAccessHandler(MmsMapping* self, ReportControl* rc, char* eleme if (rc->buffered) { - if (rc->isResync == false) + if (rc->isResync == false) { rc->reportBuffer->nextToTransmit = rc->reportBuffer->oldestReport; + rc->reportBuffer->isOverflow = true; + } rc->isResync = false; } @@ -1308,6 +1310,7 @@ Reporting_RCBWriteAccessHandler(MmsMapping* self, ReportControl* rc, char* eleme if (rc->buffered) { rc->reportBuffer->isOverflow = true; + rc->isResync = false; } else { GLOBAL_FREEMEM(rc->inclusionFlags); diff --git a/src/mms/iso_mms/server/mms_file_service.c b/src/mms/iso_mms/server/mms_file_service.c index 74c60d56..75ee5054 100644 --- a/src/mms/iso_mms/server/mms_file_service.c +++ b/src/mms/iso_mms/server/mms_file_service.c @@ -517,9 +517,9 @@ addFileEntriesToResponse(uint8_t* buffer, int bufPos, int maxBufSize, char* dire } static void -createFileDirectoryResponse(uint32_t invokeId, ByteBuffer* response, char* directoryName, char* continueAfterFileName) +createFileDirectoryResponse(uint32_t invokeId, ByteBuffer* response, int maxPduSize, char* directoryName, char* continueAfterFileName) { - int maxSize = response->maxSize - 3; /* reserve space for moreFollows */ + int maxSize = maxPduSize - 3; /* reserve space for moreFollows */ uint8_t* buffer = response->buffer; bool moreFollows = false; @@ -533,6 +533,8 @@ createFileDirectoryResponse(uint32_t invokeId, ByteBuffer* response, char* direc continueAfterFileName = NULL; } + printf("createFileDirectoryResponse: maxSize:%i\n", maxSize); + tempCurPos = addFileEntriesToResponse(buffer, tempCurPos, maxSize, directoryName, continueAfterFileName, &moreFollows); if (tempCurPos < 0) { @@ -584,6 +586,8 @@ createFileDirectoryResponse(uint32_t invokeId, ByteBuffer* response, char* direc bufPos = BerEncoder_encodeBoolean(0x81, moreFollows, buffer, bufPos); response->size = bufPos; + + printf("createFileDirectoryResponse: maxSize:%i response->isze:%i\n", maxSize, response->size); } void @@ -708,7 +712,9 @@ mmsServer_handleFileDirectoryRequest( } - createFileDirectoryResponse(invokeId, response, filename, continueAfter); + int maxPduSize = connection->maxPduSize; + + createFileDirectoryResponse(invokeId, response, maxPduSize, filename, continueAfter); } #endif /* MMS_FILE_SERVICE == 1 */ diff --git a/tools/model_generator/build-modelviewer.sh b/tools/model_generator/build-modelviewer.sh new file mode 100755 index 00000000..42d27fb2 --- /dev/null +++ b/tools/model_generator/build-modelviewer.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +mkdir build + +find src/ -name "*.java" > listFile.tmp + +javac -target 1.6 -source 1.6 -d build @listFile.tmp + +jar cfm modelviewer.jar manifest-modelviewer.mf -C build/ com/ + +rm listFile.tmp +rm -r build diff --git a/tools/model_generator/manifest-modelviewer.mf b/tools/model_generator/manifest-modelviewer.mf new file mode 100644 index 00000000..dd837e70 --- /dev/null +++ b/tools/model_generator/manifest-modelviewer.mf @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 +Main-Class: com.libiec61850.tools.ModelViewer diff --git a/tools/model_generator/src/com/libiec61850/scl/SclParser.java b/tools/model_generator/src/com/libiec61850/scl/SclParser.java index 8ed6b2c3..4ed22e51 100644 --- a/tools/model_generator/src/com/libiec61850/scl/SclParser.java +++ b/tools/model_generator/src/com/libiec61850/scl/SclParser.java @@ -62,28 +62,47 @@ public class SclParser { private List ieds; private Communication communication; private TypeDeclarations typeDeclarations; - private Node scl; + + public static boolean withOutput = true; + + public TypeDeclarations getTypeDeclarations() { + return typeDeclarations; + } - public SclParser(InputStream stream) throws SclParserException { + private Node scl; + + public SclParser(InputStream stream, boolean withOutput) throws SclParserException { + this.withOutput = withOutput; + Document doc = parseXmlDocument(stream); scl = getRootNode(doc); - System.out.println("parse data type templates ..."); + if (withOutput) + System.out.println("parse data type templates ..."); + typeDeclarations = parseTypeDeclarations(); - System.out.println("parse IED section ..."); + if (withOutput) + System.out.println("parse IED section ..."); parseIedSections(); - System.out.println("parse communication section ..."); + if (withOutput) + System.out.println("parse communication section ..."); + communication = parseCommunicationSection(); if (communication == null) - System.out.println("WARNING: No communication section found!"); + if (withOutput) + System.out.println("WARNING: No communication section found!"); + } + + public SclParser(InputStream stream) throws SclParserException { + this(stream, true); } - public IED getIedByteName(String iedName) { + public IED getIedByName(String iedName) { for (IED ied : ieds) { if (ied.getName().equals(iedName)) return ied; @@ -280,7 +299,8 @@ public class SclParser { if (connectedAP.getApName().equals(accessPointName)) { - System.out.println("Found connectedAP " + accessPointName + " for IED " + ied.getName()); + if (withOutput) + System.out.println("Found connectedAP " + accessPointName + " for IED " + ied.getName()); return connectedAP; } diff --git a/tools/model_generator/src/com/libiec61850/scl/model/DataObject.java b/tools/model_generator/src/com/libiec61850/scl/model/DataObject.java index 7a861767..818bfadd 100644 --- a/tools/model_generator/src/com/libiec61850/scl/model/DataObject.java +++ b/tools/model_generator/src/com/libiec61850/scl/model/DataObject.java @@ -82,12 +82,9 @@ public class DataObject implements DataModelNode { for (DataAttributeDefinition daDefinition : daDefinitions) { - if (daDefinition.getFc() == FunctionalConstraint.SE) { - - System.out.println("Add SG DA for corresponding SE DA: "); - this.dataAttributes.add(new DataAttribute(daDefinition, typeDeclarations, FunctionalConstraint.SG, this)); - } - + if (daDefinition.getFc() == FunctionalConstraint.SE) + this.dataAttributes.add(new DataAttribute(daDefinition, typeDeclarations, FunctionalConstraint.SG, this)); + this.dataAttributes.add(new DataAttribute(daDefinition, typeDeclarations, null, this)); diff --git a/tools/model_generator/src/com/libiec61850/scl/types/SclType.java b/tools/model_generator/src/com/libiec61850/scl/types/SclType.java index 04c9e45d..f6edac4a 100644 --- a/tools/model_generator/src/com/libiec61850/scl/types/SclType.java +++ b/tools/model_generator/src/com/libiec61850/scl/types/SclType.java @@ -26,7 +26,7 @@ import org.w3c.dom.Node; import com.libiec61850.scl.ParserUtils; import com.libiec61850.scl.SclParserException; -public class SclType { +public abstract class SclType { private String id = null; private String description; diff --git a/tools/model_generator/src/com/libiec61850/scl/types/TypeDeclarations.java b/tools/model_generator/src/com/libiec61850/scl/types/TypeDeclarations.java index 4d9999ae..2931ce15 100644 --- a/tools/model_generator/src/com/libiec61850/scl/types/TypeDeclarations.java +++ b/tools/model_generator/src/com/libiec61850/scl/types/TypeDeclarations.java @@ -68,5 +68,11 @@ public class TypeDeclarations { return null; } + + public List getTypeDeclarations() { + return typeDeclarations; + } + + } diff --git a/tools/model_generator/src/com/libiec61850/tools/DynamicModelGenerator.java b/tools/model_generator/src/com/libiec61850/tools/DynamicModelGenerator.java index 1297c623..a7fd6606 100644 --- a/tools/model_generator/src/com/libiec61850/tools/DynamicModelGenerator.java +++ b/tools/model_generator/src/com/libiec61850/tools/DynamicModelGenerator.java @@ -62,7 +62,7 @@ public class DynamicModelGenerator { if (iedName == null) ied = sclParser.getFirstIed(); else - ied = sclParser.getIedByteName(iedName); + ied = sclParser.getIedByName(iedName); if (ied == null) throw new SclParserException("No data model present in SCL file! Exit."); diff --git a/tools/model_generator/src/com/libiec61850/tools/ModelViewer.java b/tools/model_generator/src/com/libiec61850/tools/ModelViewer.java new file mode 100644 index 00000000..d364959f --- /dev/null +++ b/tools/model_generator/src/com/libiec61850/tools/ModelViewer.java @@ -0,0 +1,254 @@ +package com.libiec61850.tools; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.PrintStream; +import java.util.List; + +import com.libiec61850.scl.SclParser; +import com.libiec61850.scl.SclParserException; +import com.libiec61850.scl.model.AccessPoint; +import com.libiec61850.scl.model.DataAttribute; +import com.libiec61850.scl.model.DataObject; +import com.libiec61850.scl.model.IED; +import com.libiec61850.scl.model.LogicalDevice; +import com.libiec61850.scl.model.LogicalNode; +import com.libiec61850.scl.model.Server; +import com.libiec61850.scl.types.DataAttributeType; +import com.libiec61850.scl.types.DataObjectType; +import com.libiec61850.scl.types.EnumerationType; +import com.libiec61850.scl.types.LogicalNodeType; +import com.libiec61850.scl.types.SclType; +import com.libiec61850.scl.types.TypeDeclarations; + +public class ModelViewer { + + private static void showTypes(InputStream stream, String icdFile, PrintStream output, String iedName, String accessPointName) + throws SclParserException { + + SclParser sclParser = new SclParser(stream, false); + + TypeDeclarations typeDecl = sclParser.getTypeDeclarations(); + + for (SclType type : typeDecl.getTypeDeclarations()) { + output.print(type.getId()); + + if (type.getClass() == LogicalNodeType.class) + output.print(" : LogicalNode"); + else if (type.getClass() == DataObjectType.class) + output.print(" : DataObject"); + else if (type.getClass() == DataAttributeType.class) + output.print(" : DataAttribute"); + else if (type.getClass() == EnumerationType.class) + output.print(" : Enumeration"); + + output.println(); + } + } + + private static void printSubAttributes(DataAttribute attribute, PrintStream output, String indent, String add) { + + if (attribute.getSubDataAttributes() != null) { + + for (DataAttribute attr : attribute.getSubDataAttributes()) { + output.println(indent + add + attr.getName()); + + printSubAttributes(attr, output, indent + add, add); + } + } + } + + private static void printModelStructure(InputStream stream, String icdFile, PrintStream output, String iedName, String accessPointName) + throws SclParserException { + + SclParser sclParser = new SclParser(stream, false); + + IED ied = null; + + if (iedName == null) + ied = sclParser.getFirstIed(); + else + ied = sclParser.getIedByName(iedName); + + AccessPoint ap = ied.getFirstAccessPoint(); + + Server server = ap.getServer(); + + List devices = server.getLogicalDevices(); + + for (LogicalDevice device : devices) { + output.println(device.getInst()); + + List lNodes = device.getLogicalNodes(); + + for (LogicalNode lNode : lNodes) { + output.println(" " + lNode.getName()); + + for (DataObject dObject : lNode.getDataObjects()) { + output.println(" " + dObject.getName()); + + for (DataAttribute dAttribute : dObject.getDataAttributes()) { + output.println(" " + dAttribute.getName() + " [" + dAttribute.getFc().toString() + "]"); + + printSubAttributes(dAttribute, output, " ", " "); + } + + } + } + } + + } + + + private static void printSubAttributeList(DataAttribute attribute, PrintStream output, String prefix) { + + if (attribute.getSubDataAttributes() != null) { + + for (DataAttribute attr : attribute.getSubDataAttributes()) { + + String nextPrefix = prefix + "." + attr.getName(); + + output.println(nextPrefix + " [" + attr.getFc() + "]"); + + printSubAttributeList(attr, output, nextPrefix); + } + } + } + + + private static void printAttributeList(InputStream stream, String icdFile, PrintStream output, String iedName, String accessPointName) + throws SclParserException { + + SclParser sclParser = new SclParser(stream, false); + + IED ied = null; + + if (iedName == null) + ied = sclParser.getFirstIed(); + else + ied = sclParser.getIedByName(iedName); + + AccessPoint ap = ied.getFirstAccessPoint(); + + Server server = ap.getServer(); + + List devices = server.getLogicalDevices(); + + + + for (LogicalDevice device : devices) { + + String devPrefix = ied.getName() + device.getInst() + "/"; + + List lNodes = device.getLogicalNodes(); + + for (LogicalNode lNode : lNodes) { + String lNodePrefix = devPrefix + lNode.getName(); + + for (DataObject dObject : lNode.getDataObjects()) { + + String dOPrefix = lNodePrefix + "." + dObject.getName(); + + for (DataAttribute dAttribute : dObject.getDataAttributes()) { + + String daPrefix = dOPrefix + "." + dAttribute.getName(); + + output.println(daPrefix + " [" + dAttribute.getFc().toString() + "]"); + + printSubAttributeList(dAttribute, output, daPrefix); + } + + } + } + } + + } + + public static void main(String[] args) throws FileNotFoundException { + + if (args.length < 1) { + System.out.println("SCL model viewer"); + System.out.println("Usage: scltool [-ied ] [-ap ] [-t] [-s] [-a] []"); + System.out.println(" -ied select IED"); + System.out.println(" -ap select AP"); + System.out.println(" -t print type list"); + System.out.println(" -s print IED device model structure"); + System.out.println(" -a print list of data attributes (object references)"); + System.exit(1); + } + + String icdFile = args[0]; + + PrintStream outputStream = System.out; + + String accessPointName = null; + String iedName = null; + + boolean printTypeList = false; + boolean printModelStructure = false; + boolean printDataAttribtues = false; + + if (args.length > 1) { + for (int i = 1; i < args.length; i++) { + if (args[i].equals("-ap")) { + accessPointName = args[i+1]; + + System.out.println("Select access point " + accessPointName); + + i++; + } + else if (args[i].equals("-ied")) { + iedName = args[i+1]; + + System.out.println("Select IED " + iedName); + + i++; + + } + else if (args[i].equals("-t")) { + printTypeList = true; + + i++; + + } + else if (args[i].equals("-s")) { + printModelStructure = true; + + i++; + + } + else if (args[i].equals("-a")) { + printDataAttribtues = true; + + i++; + + } + else { + outputStream = new PrintStream(new FileOutputStream(new File(args[i]))); + } + } + + } + + InputStream stream = new FileInputStream(icdFile); + + try { + if (printTypeList) + showTypes(stream, icdFile, outputStream, iedName, accessPointName); + + if (printModelStructure) + printModelStructure(stream, icdFile, outputStream, iedName, accessPointName); + + if (printDataAttribtues) + printAttributeList(stream, icdFile, outputStream, iedName, accessPointName); + + + } catch (SclParserException e) { + System.err.println("ERROR: " + e.getMessage()); + } + } + +} diff --git a/tools/model_generator/src/com/libiec61850/tools/StaticModelGenerator.java b/tools/model_generator/src/com/libiec61850/tools/StaticModelGenerator.java index cad7d5ec..a0b1ea6d 100644 --- a/tools/model_generator/src/com/libiec61850/tools/StaticModelGenerator.java +++ b/tools/model_generator/src/com/libiec61850/tools/StaticModelGenerator.java @@ -129,7 +129,7 @@ public class StaticModelGenerator { if (iedName == null) ied = sclParser.getFirstIed(); else - ied = sclParser.getIedByteName(iedName); + ied = sclParser.getIedByName(iedName); if (ied == null) System.out.println("IED model not found in SCL file! Exit.");