diff --git a/config/stack_config.h b/config/stack_config.h
index 3c8467f..da921a3 100644
--- a/config/stack_config.h
+++ b/config/stack_config.h
@@ -98,6 +98,16 @@
/* 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 CONFIG_GOOSE_CONFREV_WRITABLE 0
+#define CONFIG_GOOSE_NDSCOM_WRITABLE 0
+#define CONFIG_GOOSE_DSTADDRESS_WRITABLE 0
+#define CONFIG_GOOSE_MINTIME_WRITABLE 0
+#define CONFIG_GOOSE_MAXTIME_WRITABLE 0
+#define CONFIG_GOOSE_FIXEDOFFS_WRITABLE 0
+
/* The default value for the priority field of the 802.1Q header (allowed range 0-7) */
#define CONFIG_GOOSE_DEFAULT_PRIORITY 4
diff --git a/config/stack_config.h.cmake b/config/stack_config.h.cmake
index 46c76f8..d91bc67 100644
--- a/config/stack_config.h.cmake
+++ b/config/stack_config.h.cmake
@@ -96,6 +96,16 @@
/* 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 CONFIG_GOOSE_CONFREV_WRITABLE 1
+#define CONFIG_GOOSE_NDSCOM_WRITABLE 1
+#define CONFIG_GOOSE_DSTADDRESS_WRITABLE 1
+#define CONFIG_GOOSE_MINTIME_WRITABLE 1
+#define CONFIG_GOOSE_MAXTIME_WRITABLE 1
+#define CONFIG_GOOSE_FIXEDOFFS_WRITABLE 1
+
/* The default value for the priority field of the 802.1Q header (allowed range 0-7) */
#define CONFIG_GOOSE_DEFAULT_PRIORITY 4
diff --git a/examples/server_example_goose/simpleIO_direct_control_goose.icd b/examples/server_example_goose/simpleIO_direct_control_goose.icd
index 5f68fa0..3efbf70 100644
--- a/examples/server_example_goose/simpleIO_direct_control_goose.icd
+++ b/examples/server_example_goose/simpleIO_direct_control_goose.icd
@@ -77,7 +77,7 @@
-
+
diff --git a/examples/server_example_goose/static_model.c b/examples/server_example_goose/static_model.c
index e1bcf92..0bddaaf 100644
--- a/examples/server_example_goose/static_model.c
+++ b/examples/server_example_goose/static_model.c
@@ -1983,7 +1983,7 @@ static PhyComAddress iedModel_GenericIO_LLN0_gse0_address = {
{0x1, 0xc, 0xcd, 0x1, 0x0, 0x1}
};
-GSEControlBlock iedModel_GenericIO_LLN0_gse0 = {&iedModel_GenericIO_LLN0, "gcbEvents", "events", "Events", 2, false,&iedModel_GenericIO_LLN0_gse0_address, &iedModel_GenericIO_LLN0_gse1};
+GSEControlBlock iedModel_GenericIO_LLN0_gse0 = {&iedModel_GenericIO_LLN0, "gcbEvents", "events", "Events", 2, false, &iedModel_GenericIO_LLN0_gse0_address, 1000, 3000, &iedModel_GenericIO_LLN0_gse1};
static PhyComAddress iedModel_GenericIO_LLN0_gse1_address = {
4,
@@ -1992,7 +1992,7 @@ static PhyComAddress iedModel_GenericIO_LLN0_gse1_address = {
{0x1, 0xc, 0xcd, 0x1, 0x0, 0x1}
};
-GSEControlBlock iedModel_GenericIO_LLN0_gse1 = {&iedModel_GenericIO_LLN0, "gcbAnalogValues", "analog", "AnalogValues", 2, false,&iedModel_GenericIO_LLN0_gse1_address, NULL};
+GSEControlBlock iedModel_GenericIO_LLN0_gse1 = {&iedModel_GenericIO_LLN0, "gcbAnalogValues", "analog", "AnalogValues", 2, false, &iedModel_GenericIO_LLN0_gse1_address, -1, -1, NULL};
diff --git a/src/iec61850/inc/iec61850_dynamic_model.h b/src/iec61850/inc/iec61850_dynamic_model.h
index 43d1182..84b0239 100644
--- a/src/iec61850/inc/iec61850_dynamic_model.h
+++ b/src/iec61850/inc/iec61850_dynamic_model.h
@@ -171,11 +171,14 @@ SettingGroupControlBlock_create(LogicalNode* parent, uint8_t actSG, uint8_t numO
* \param dataSet the data set reference to be used by the GoCB
* \param confRef the configuration revision
* \param fixedOffs indicates if GOOSE publisher shall use fixed offsets (NOT YET SUPPORTED)
+ * \param minTime minimum GOOSE retransmission time (-1 if not specified - uses stack default then)
+ * \param maxTime GOOSE retransmission time in stable state (-1 if not specified - uses stack default then)
*
* \return the new GoCB instance
*/
GSEControlBlock*
-GSEControlBlock_create(const char* name, LogicalNode* parent, char* appId, char* dataSet, uint32_t confRef, bool fixedOffs);
+GSEControlBlock_create(const char* name, LogicalNode* parent, char* appId, char* dataSet, uint32_t confRef,
+ bool fixedOffs, int minTime, int maxTime);
/**
* \brief create a PhyComAddress object and add it to a GoCB
diff --git a/src/iec61850/inc/iec61850_model.h b/src/iec61850/inc/iec61850_model.h
index a4a091a..f8d36e6 100644
--- a/src/iec61850/inc/iec61850_model.h
+++ b/src/iec61850/inc/iec61850_model.h
@@ -247,7 +247,8 @@ struct sGSEControlBlock {
uint32_t confRef; /* ConfRef - configuration revision */
bool fixedOffs; /* fixed offsets */
PhyComAddress* address; /* GSE communication parameters */
-
+ int minTime; /* optional minTime parameter --> -1 if not present */
+ int maxTime; /* optional maxTime parameter --> -1 if not present */
GSEControlBlock* sibling; /* next control block in list or NULL if this is the last entry */
};
diff --git a/src/iec61850/server/mms_mapping/mms_goose.c b/src/iec61850/server/mms_mapping/mms_goose.c
index 15bf0dd..e4c0678 100644
--- a/src/iec61850/server/mms_mapping/mms_goose.c
+++ b/src/iec61850/server/mms_mapping/mms_goose.c
@@ -57,6 +57,9 @@ struct sMmsGooseControlBlock {
uint64_t nextPublishTime;
int retransmissionsLeft; /* number of retransmissions left for the last event */
+ int minTime;
+ int maxTime;
+
#if (CONFIG_MMS_THREADLESS_STACK != 1)
Semaphore publisherMutex;
#endif
@@ -223,7 +226,10 @@ MmsGooseControlBlock_enable(MmsGooseControlBlock self)
self->publisher = GoosePublisher_create(&commParameters, self->mmsMapping->gooseInterfaceId);
- GoosePublisher_setTimeAllowedToLive(self->publisher, CONFIG_GOOSE_STABLE_STATE_TRANSMISSION_INTERVAL * 3);
+ self->minTime = MmsValue_toUint32(MmsValue_getElement(self->mmsValue, 6));
+ self->maxTime = MmsValue_toUint32(MmsValue_getElement(self->mmsValue, 7));
+
+ GoosePublisher_setTimeAllowedToLive(self->publisher, self->maxTime * 3);
GoosePublisher_setDataSetRef(self->publisher, self->dataSetRef);
@@ -555,6 +561,22 @@ GOOSE_createGOOSEControlBlocks(MmsMapping* self, MmsDomain* domain,
mmsGCB->domain = domain;
mmsGCB->logicalNode = logicalNode;
+ if (gooseControlBlock->minTime == -1)
+ mmsGCB->minTime = CONFIG_GOOSE_EVENT_RETRANSMISSION_INTERVAL;
+ else
+ mmsGCB->minTime = gooseControlBlock->minTime;
+
+ if (gooseControlBlock->maxTime == -1)
+ mmsGCB->maxTime = CONFIG_GOOSE_STABLE_STATE_TRANSMISSION_INTERVAL;
+ else
+ mmsGCB->maxTime = gooseControlBlock->maxTime;
+
+ MmsValue* minTime = MmsValue_getElement(gseValues, 6);
+ MmsValue_setUint32(minTime, mmsGCB->minTime);
+
+ MmsValue* maxTime = MmsValue_getElement(gseValues, 7);
+ MmsValue_setUint32(maxTime, mmsGCB->maxTime);
+
mmsGCB->mmsMapping = self;
LinkedList_add(self->gseControls, mmsGCB);
diff --git a/src/iec61850/server/mms_mapping/mms_mapping.c b/src/iec61850/server/mms_mapping/mms_mapping.c
index 07ee68f..881d1b6 100644
--- a/src/iec61850/server/mms_mapping/mms_mapping.c
+++ b/src/iec61850/server/mms_mapping/mms_mapping.c
@@ -1321,6 +1321,38 @@ lookupGCB(MmsMapping* self, MmsDomain* domain, char* lnName, char* objectName)
return NULL;
}
+#ifndef CONFIG_GOOSE_GOID_WRITABLE
+#define CONFIG_GOOSE_GOID_WRITABLE 0
+#endif
+
+#ifndef CONFIG_GOOSE_DATSET_WRITABLE
+#define CONFIG_GOOSE_DATSET_WRITABLE 0
+#endif
+
+#ifndef CONFIG_GOOSE_CONFREV_WRITABLE
+#define CONFIG_GOOSE_CONFREV_WRITABLE 0
+#endif
+
+#ifndef CONFIG_GOOSE_NDSCOM_WRITABLE
+#define CONFIG_GOOSE_NDSCOM_WRITABLE 0
+#endif
+
+#ifndef CONFIG_GOOSE_DSTADDRESS_WRITABLE
+#define CONFIG_GOOSE_DSTADDRESS_WRITABLE 0
+#endif
+
+#ifndef CONFIG_GOOSE_MINTIME_WRITABLE
+#define CONFIG_GOOSE_MINTIME_WRITABLE 0
+#endif
+
+#ifndef CONFIG_GOOSE_MAXTIME_WRITABLE
+#define CONFIG_GOOSE_MAXTIME_WRITABLE 0
+#endif
+
+#ifndef CONFIG_GOOSE_FIXEDOFFS_WRITABLE
+#define CONFIG_GOOSE_FIXEDOFFS_WRITABLE 0
+#endif
+
static MmsDataAccessError
writeAccessGooseControlBlock(MmsMapping* self, MmsDomain* domain, char* variableIdOrig,
MmsValue* value)
@@ -1370,16 +1402,77 @@ writeAccessGooseControlBlock(MmsMapping* self, MmsDomain* domain, char* variable
if (MmsGooseControlBlock_isEnabled(mmsGCB))
return DATA_ACCESS_ERROR_TEMPORARILY_UNAVAILABLE;
else {
- MmsValue* subValue = MmsValue_getSubElement(MmsGooseControlBlock_getMmsValues(mmsGCB),
+ bool allowAccess = false;
+
+#if (CONFIG_GOOSE_GOID_WRITABLE == 1)
+ if (strcmp(varName, "GoID") == 0) {
+ MmsValue_update(MmsValue_getElement(MmsGooseControlBlock_getMmsValues(mmsGCB), 1), value);
+ allowAccess = true;
+ }
+#endif
+
+#if (CONFIG_GOOSE_DATSET_WRITABLE == 1)
+ if (strcmp(varName, "DatSet") == 0) {
+ MmsValue_update(MmsValue_getElement(MmsGooseControlBlock_getMmsValues(mmsGCB), 2), value);
+ allowAccess = true;
+ }
+#endif
+
+#if (CONFIG_GOOSE_CONFREV_WRITABLE == 1)
+ if (strcmp(varName, "ConfRev") == 0) {
+ MmsValue_update(MmsValue_getElement(MmsGooseControlBlock_getMmsValues(mmsGCB), 3), value);
+ allowAccess = true;
+ }
+#endif
+
+#if (CONFIG_GOOSE_NDSCOM_WRITABLE == 1)
+ if (strcmp(varName, "NdsCom") == 0) {
+ MmsValue_update(MmsValue_getElement(MmsGooseControlBlock_getMmsValues(mmsGCB), 4), value);
+ allowAccess = true;
+ }
+#endif
+
+#if (CONFIG_GOOSE_DSTADDRESS_WRITABLE == 1)
+ if (memcmp(varName, "DstAddress", 9) == 0) {
+ MmsValue* subValue = MmsValue_getSubElement(MmsGooseControlBlock_getMmsValues(mmsGCB),
MmsGooseControlBlock_getVariableSpecification(mmsGCB), varName);
- if (subValue == NULL)
- return DATA_ACCESS_ERROR_INVALID_ADDRESS;
+ if (subValue == NULL)
+ return DATA_ACCESS_ERROR_INVALID_ADDRESS;
- if (MmsValue_update(subValue, value))
+ if (MmsValue_update(subValue, value))
+ return DATA_ACCESS_ERROR_SUCCESS;
+ else
+ return DATA_ACCESS_ERROR_OBJECT_VALUE_INVALID;
+ }
+#endif
+
+#if (CONFIG_GOOSE_MINTIME_WRITABLE == 1)
+ if (strcmp(varName, "MinTime") == 0) {
+ MmsValue_update(MmsValue_getElement(MmsGooseControlBlock_getMmsValues(mmsGCB), 6), value);
+ allowAccess = true;
+ }
+#endif
+
+#if (CONFIG_GOOSE_MAXTIME_WRITABLE == 1)
+ if (strcmp(varName, "MaxTime") == 0) {
+ MmsValue_update(MmsValue_getElement(MmsGooseControlBlock_getMmsValues(mmsGCB), 7), value);
+ allowAccess = true;
+ }
+#endif
+
+#if (CONFIG_GOOSE_FIXEDOFFS_WRITABLE == 1)
+ if (strcmp(varName, "FixedOffs") == 0) {
+ MmsValue_update(MmsValue_getElement(MmsGooseControlBlock_getMmsValues(mmsGCB), 8), value);
+ allowAccess = true;
+ }
+#endif
+
+ if (allowAccess)
return DATA_ACCESS_ERROR_SUCCESS;
else
- return DATA_ACCESS_ERROR_OBJECT_VALUE_INVALID;
+ return DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED;
+
}
}
}
diff --git a/src/iec61850/server/model/config_file_parser.c b/src/iec61850/server/model/config_file_parser.c
index 0e4d353..fb22fb9 100644
--- a/src/iec61850/server/model/config_file_parser.c
+++ b/src/iec61850/server/model/config_file_parser.c
@@ -221,15 +221,16 @@ ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle)
else if (StringUtils_startsWith((char*) lineBuffer, "GC")) {
uint32_t confRef;
int fixedOffs;
+ int minTime = -1;
+ int maxTime = -1;
- int matchedItems = sscanf((char*) lineBuffer, "GC(%s %s %s %u %i)",
- nameString, nameString2, nameString3, &confRef, &fixedOffs);
-
+ int matchedItems = sscanf((char*) lineBuffer, "GC(%s %s %s %u %i %i %i)",
+ nameString, nameString2, nameString3, &confRef, &fixedOffs, &minTime, &maxTime);
if (matchedItems < 5) goto exit_error;
currentGoCB = GSEControlBlock_create(nameString, currentLN, nameString2,
- nameString3, confRef, fixedOffs);
+ nameString3, confRef, fixedOffs, minTime, maxTime);
indendation = 4;
@@ -257,7 +258,7 @@ ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle)
#endif /* (CONFIG_IEC61850_SETTING_GROUPS == 1) */
else {
- // if (DEBUG_IED_SERVER)
+ if (DEBUG_IED_SERVER)
printf("IED_SERVER: Unknown identifier (%s)\n", lineBuffer);
goto exit_error;
@@ -430,7 +431,7 @@ ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle)
return model;
exit_error:
- // if (DEBUG_IED_SERVER)
+ if (DEBUG_IED_SERVER)
printf("IED_SERVER: error parsing line %i (indendation level = %i)\n", currentLine, indendation);
IedModel_destroy(model);
return NULL;
diff --git a/src/iec61850/server/model/dynamic_model.c b/src/iec61850/server/model/dynamic_model.c
index f536d47..5be7348 100644
--- a/src/iec61850/server/model/dynamic_model.c
+++ b/src/iec61850/server/model/dynamic_model.c
@@ -302,7 +302,8 @@ LogicalNode_addGSEControlBlock(LogicalNode* self, GSEControlBlock* gcb)
}
GSEControlBlock*
-GSEControlBlock_create(const char* name, LogicalNode* parent, char* appId, char* dataSet, uint32_t confRef, bool fixedOffs)
+GSEControlBlock_create(const char* name, LogicalNode* parent, char* appId, char* dataSet, uint32_t confRef, bool fixedOffs,
+ int minTime, int maxTime)
{
GSEControlBlock* self = (GSEControlBlock*) GLOBAL_MALLOC(sizeof(GSEControlBlock));
@@ -321,6 +322,8 @@ GSEControlBlock_create(const char* name, LogicalNode* parent, char* appId, char*
self->confRef = confRef;
self->fixedOffs = fixedOffs;
+ self->minTime = minTime;
+ self->maxTime = maxTime;
self->address = NULL;
diff --git a/src/mms/inc_private/mms_server_internal.h b/src/mms/inc_private/mms_server_internal.h
index 4dede14..000936d 100644
--- a/src/mms/inc_private/mms_server_internal.h
+++ b/src/mms/inc_private/mms_server_internal.h
@@ -124,7 +124,7 @@ struct sMmsServerConnection {
int maxServOutstandingCalling;
int maxServOutstandingCalled;
int dataStructureNestingLevel;
- int maxPduSize; /* local detail */
+ uint32_t maxPduSize; /* local detail */
IsoConnection isoConnection;
MmsServer server;
uint32_t lastInvokeId;
diff --git a/src/mms/iso_mms/server/mms_read_service.c b/src/mms/iso_mms/server/mms_read_service.c
index 30cf343..6ad75e4 100644
--- a/src/mms/iso_mms/server/mms_read_service.c
+++ b/src/mms/iso_mms/server/mms_read_service.c
@@ -322,27 +322,27 @@ static int
encodeVariableAccessSpecification(VarAccessSpec* accessSpec, uint8_t* buffer, int bufPos, bool encode)
{
/* determine size */
- int varAccessSpecSize = 0;
+ uint32_t varAccessSpecSize = 0;
- int itemIdLen = strlen(accessSpec->itemId);
+ uint32_t itemIdLen = strlen(accessSpec->itemId);
varAccessSpecSize += itemIdLen + BerEncoder_determineLengthSize(itemIdLen) + 1;
if (accessSpec->domainId != NULL) {
- int domainIdLen = strlen(accessSpec->domainId);
+ uint32_t domainIdLen = strlen(accessSpec->domainId);
varAccessSpecSize += domainIdLen + BerEncoder_determineLengthSize(domainIdLen) + 1;
}
- int specificityLength = varAccessSpecSize;
+ uint32_t specificityLength = varAccessSpecSize;
varAccessSpecSize += 1 + BerEncoder_determineLengthSize(specificityLength);
- int variableListNameLength = varAccessSpecSize;
+ uint32_t variableListNameLength = varAccessSpecSize;
varAccessSpecSize += 1 + BerEncoder_determineLengthSize(variableListNameLength);
- int varAccessSpecLength = varAccessSpecSize;
+ uint32_t varAccessSpecLength = varAccessSpecSize;
varAccessSpecSize += 1 + BerEncoder_determineLengthSize(varAccessSpecLength);
@@ -389,14 +389,14 @@ encodeReadResponse(MmsServerConnection connection,
int variableCount = LinkedList_size(values);
- int varAccessSpecSize = 0;
+ uint32_t varAccessSpecSize = 0;
if (accessSpec != NULL) {
varAccessSpecSize = encodeVariableAccessSpecification(accessSpec, NULL, 0, false);
}
/* determine BER encoded message sizes */
- int accessResultSize = 0;
+ uint32_t accessResultSize = 0;
/* iterate values list to determine encoded size */
LinkedList value = LinkedList_getNext(values);
@@ -410,21 +410,21 @@ encodeReadResponse(MmsServerConnection connection,
value = LinkedList_getNext(value);
}
- int listOfAccessResultsLength = 1 +
+ uint32_t listOfAccessResultsLength = 1 +
BerEncoder_determineLengthSize(accessResultSize) +
accessResultSize;
- int confirmedServiceResponseContentLength = listOfAccessResultsLength + varAccessSpecSize;
+ uint32_t confirmedServiceResponseContentLength = listOfAccessResultsLength + varAccessSpecSize;
- int confirmedServiceResponseLength = 1 +
+ uint32_t confirmedServiceResponseLength = 1 +
BerEncoder_determineLengthSize(confirmedServiceResponseContentLength) +
confirmedServiceResponseContentLength;
- int invokeIdSize = BerEncoder_UInt32determineEncodedSize(invokeId) + 2;
+ uint32_t invokeIdSize = BerEncoder_UInt32determineEncodedSize(invokeId) + 2;
- int confirmedResponseContentSize = confirmedServiceResponseLength + invokeIdSize;
+ uint32_t confirmedResponseContentSize = confirmedServiceResponseLength + invokeIdSize;
- int mmsPduSize = 1 + BerEncoder_determineLengthSize(confirmedResponseContentSize) +
+ uint32_t mmsPduSize = 1 + BerEncoder_determineLengthSize(confirmedResponseContentSize) +
confirmedResponseContentSize;
/* Check if message would fit in the MMS PDU */
diff --git a/tools/model_generator/genconfig.jar b/tools/model_generator/genconfig.jar
index bd3666a..625d0eb 100644
Binary files a/tools/model_generator/genconfig.jar and b/tools/model_generator/genconfig.jar differ
diff --git a/tools/model_generator/genmodel.jar b/tools/model_generator/genmodel.jar
index 4ad96ab..e2af5a1 100644
Binary files a/tools/model_generator/genmodel.jar and b/tools/model_generator/genmodel.jar differ
diff --git a/tools/model_generator/src/com/libiec61850/scl/model/GSEControl.java b/tools/model_generator/src/com/libiec61850/scl/model/GSEControl.java
index 68d79a1..40ee837 100644
--- a/tools/model_generator/src/com/libiec61850/scl/model/GSEControl.java
+++ b/tools/model_generator/src/com/libiec61850/scl/model/GSEControl.java
@@ -34,6 +34,8 @@ public class GSEControl {
private int confRev = 1;
private String appID;
private boolean fixedOffs = false;
+ private int minTime = -1;
+ private int maxTime = -1;
public GSEControl(Node gseControlNode) throws SclParserException {
@@ -53,6 +55,15 @@ public class GSEControl {
if (fixedOffs != null)
this.fixedOffs = fixedOffs;
+ String minTimeStr = ParserUtils.parseAttribute(gseControlNode, "minTime");
+ String maxTimeStr = ParserUtils.parseAttribute(gseControlNode, "maxTime");
+
+ if (minTimeStr != null)
+ minTime = new Integer(minTimeStr);
+
+ if (maxTimeStr != null)
+ maxTime = new Integer(maxTimeStr);
+
String typeString = ParserUtils.parseAttribute(gseControlNode, "type");
if (typeString != null)
@@ -84,5 +95,13 @@ public class GSEControl {
public boolean isFixedOffs() {
return fixedOffs;
}
+
+ public int getMinTime() {
+ return minTime;
+ }
+
+ public int getMaxTime() {
+ return maxTime;
+ }
}
diff --git a/tools/model_generator/src/com/libiec61850/tools/DynamicModelGenerator.java b/tools/model_generator/src/com/libiec61850/tools/DynamicModelGenerator.java
index 03d3cc6..ac47251 100644
--- a/tools/model_generator/src/com/libiec61850/tools/DynamicModelGenerator.java
+++ b/tools/model_generator/src/com/libiec61850/tools/DynamicModelGenerator.java
@@ -161,7 +161,12 @@ public class DynamicModelGenerator {
output.print('1');
else
output.print('0');
-
+ output.print(' ');
+ output.print(gcb.getMinTime());
+ output.print(' ');
+ output.print(gcb.getMaxTime());
+ output.print(' ');
+
if (gseAddress == null) {
output.println(");");
}
diff --git a/tools/model_generator/src/com/libiec61850/tools/StaticModelGenerator.java b/tools/model_generator/src/com/libiec61850/tools/StaticModelGenerator.java
index ba23d76..22ad738 100644
--- a/tools/model_generator/src/com/libiec61850/tools/StaticModelGenerator.java
+++ b/tools/model_generator/src/com/libiec61850/tools/StaticModelGenerator.java
@@ -754,14 +754,17 @@ public class StaticModelGenerator {
gseString += gseControlBlock.getConfRev() + ", ";
if (gseControlBlock.isFixedOffs())
- gseString += "true,";
+ gseString += "true, ";
else
- gseString += "false,";
+ gseString += "false, ";
if (gseAddress != null)
gseString += "&" + phyComAddrName + ", ";
else
gseString += "NULL, ";
+
+ gseString += gseControlBlock.getMinTime() + ", ";
+ gseString += gseControlBlock.getMaxTime() + ", ";
currentGseVariableNumber++;