diff --git a/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs b/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs
index 7aa303ba..5126b30e 100644
--- a/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs
+++ b/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs
@@ -1529,6 +1529,8 @@ namespace IEC61850
entryId = octetStringVal.getOctetString();
+ octetStringVal.Dispose();
+
return entryId;
}
else
diff --git a/dotnet/IEC61850forCSharp/IedServerConfig.cs b/dotnet/IEC61850forCSharp/IedServerConfig.cs
index 9738f4ad..33365792 100644
--- a/dotnet/IEC61850forCSharp/IedServerConfig.cs
+++ b/dotnet/IEC61850forCSharp/IedServerConfig.cs
@@ -124,6 +124,13 @@ namespace IEC61850.Server
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedServerConfig_useIntegratedGoosePublisher(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool enable);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
+ static extern bool IedServerConfig_getSyncIntegrityReportTimes(IntPtr self);
+
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern void IedServerConfig_setSyncIntegrityReportTimes(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool enable);
+
internal IntPtr self;
public IedServerConfig()
@@ -351,6 +358,27 @@ namespace IEC61850.Server
}
}
+ ///
+ /// Enable/Disable synchoronized integrity report times (disabled by default)
+ ///
+ ///
+ /// When this flag is enabled the integrity report generation times are
+ /// aligned with the UTC epoch. Then the unix time stamps are straight multiples of the
+ /// integrity interval.
+ ///
+ /// true if sync integrity report times; otherwise, false.
+ public bool SyncIntegrityReportTimes
+ {
+ get
+ {
+ return IedServerConfig_getSyncIntegrityReportTimes(self);
+ }
+ set
+ {
+ IedServerConfig_setSyncIntegrityReportTimes(self, value);
+ }
+ }
+
///
/// Releases all resource used by the object.
///
diff --git a/src/iec61850/inc/iec61850_server.h b/src/iec61850/inc/iec61850_server.h
index 48c79533..78ada2bf 100644
--- a/src/iec61850/inc/iec61850_server.h
+++ b/src/iec61850/inc/iec61850_server.h
@@ -96,6 +96,9 @@ struct sIedServerConfig
/** RCB has owner attribute (default: true) */
bool enableOwnerForRCB;
+
+ /** integrity report start times will by synchronized with straight numbers (default: false) */
+ bool syncIntegrityReportTimes;
};
/**
@@ -179,6 +182,30 @@ IedServerConfig_setMaxMmsConnections(IedServerConfig self, int maxConnections);
LIB61850_API int
IedServerConfig_getMaxMmsConnections(IedServerConfig self);
+/**
+ * \brief Enable synchronized integrity report times
+ *
+ * NOTE: When this flag is enabled the integrity report generation times are
+ * aligned with the UTC epoch. Then the unix time stamps are straight multiples of the
+ * integrity interval.
+ *
+ * \param enable when true synchronized integrity report times are enabled
+ */
+void
+IedServerConfig_setSyncIntegrityReportTimes(IedServerConfig self, bool enable);
+
+/**
+ * \brief Check if synchronized integrity report times are enabled
+ *
+ * NOTE: When this flag is enabled the integrity report generation times are
+ * aligned with the UTC epoch. Then the unix time stamps are straight multiples of the
+ * integrity interval.
+ *
+ * \return true, when enabled, false otherwise
+ */
+bool
+IedServerConfig_getSyncIntegrityReportTimes(IedServerConfig self);
+
/**
* \brief Set the basepath of the file services
*
@@ -1549,7 +1576,7 @@ typedef enum {
RCB_EVENT_GI, /* << GI report triggered */
RCB_EVENT_PURGEBUF, /* << Purge buffer procedure executed */
RCB_EVENT_OVERFLOW, /* << Report buffer overflow */
- RCB_EVENT_REPORT_CREATED /* << a new report was created and inserted into the buffer */
+ RCB_EVENT_REPORT_CREATED /* << A new report was created and inserted into the buffer */
} IedServer_RCBEventType;
/**
diff --git a/src/iec61850/inc_private/ied_server_private.h b/src/iec61850/inc_private/ied_server_private.h
index ed6af512..14a694b1 100644
--- a/src/iec61850/inc_private/ied_server_private.h
+++ b/src/iec61850/inc_private/ied_server_private.h
@@ -49,6 +49,7 @@ struct sIedServer
int reportBufferSizeURCBs;
bool enableBRCBResvTms;
bool enableOwnerForRCB;
+ bool syncIntegrityReportTimes;
#endif
#if (CONFIG_MMS_THREADLESS_STACK != 1)
diff --git a/src/iec61850/inc_private/mms_mapping_internal.h b/src/iec61850/inc_private/mms_mapping_internal.h
index 79c9e793..3e896495 100644
--- a/src/iec61850/inc_private/mms_mapping_internal.h
+++ b/src/iec61850/inc_private/mms_mapping_internal.h
@@ -323,7 +323,9 @@ struct sMmsMapping {
#endif /* (CONFIG_IEC61850_SERVICE_TRACKING == 1) */
/* flag indicates if data model is locked --> prevents reports to be sent */
+
bool isModelLocked;
+ Semaphore isModelLockedMutex;
IedServer iedServer;
diff --git a/src/iec61850/server/impl/ied_server.c b/src/iec61850/server/impl/ied_server.c
index cf2e0bdc..9462d3a3 100644
--- a/src/iec61850/server/impl/ied_server.c
+++ b/src/iec61850/server/impl/ied_server.c
@@ -485,11 +485,13 @@ IedServer_createWithConfig(IedModel* dataModel, TLSConfiguration tlsConfiguratio
self->reportBufferSizeURCBs = serverConfiguration->reportBufferSizeURCBs;
self->enableBRCBResvTms = serverConfiguration->enableResvTmsForBRCB;
self->enableOwnerForRCB = serverConfiguration->enableOwnerForRCB;
+ self->syncIntegrityReportTimes = serverConfiguration->syncIntegrityReportTimes;
}
else {
self->reportBufferSizeBRCBs = CONFIG_REPORTING_DEFAULT_REPORT_BUFFER_SIZE;
self->reportBufferSizeURCBs = CONFIG_REPORTING_DEFAULT_REPORT_BUFFER_SIZE;
self->enableOwnerForRCB = false;
+ self->syncIntegrityReportTimes = false;
#if (CONFIG_IEC61850_BRCB_WITH_RESVTMS == 1)
self->enableBRCBResvTms = true;
#else
@@ -812,9 +814,13 @@ IedServer_stopThreadless(IedServer self)
void
IedServer_lockDataModel(IedServer self)
{
+ Semaphore_wait(self->mmsMapping->isModelLockedMutex);
+
MmsServer_lockModel(self->mmsServer);
self->mmsMapping->isModelLocked = true;
+
+ Semaphore_post(self->mmsMapping->isModelLockedMutex);
}
void
@@ -828,9 +834,13 @@ IedServer_unlockDataModel(IedServer self)
/* check if reports have to be sent! */
Reporting_processReportEventsAfterUnlock(self->mmsMapping);
+ Semaphore_wait(self->mmsMapping->isModelLockedMutex);
+
self->mmsMapping->isModelLocked = false;
MmsServer_unlockModel(self->mmsServer);
+
+ Semaphore_post(self->mmsMapping->isModelLockedMutex);
}
#if (CONFIG_IEC61850_CONTROL_SERVICE == 1)
diff --git a/src/iec61850/server/impl/ied_server_config.c b/src/iec61850/server/impl/ied_server_config.c
index c87e1200..fdc38f8e 100644
--- a/src/iec61850/server/impl/ied_server_config.c
+++ b/src/iec61850/server/impl/ied_server_config.c
@@ -58,6 +58,7 @@ IedServerConfig_create()
self->enableResvTmsForSGCB = true;
self->enableResvTmsForBRCB = true;
self->enableOwnerForRCB = false;
+ self->syncIntegrityReportTimes = false;
}
return self;
@@ -251,3 +252,15 @@ IedServerConfig_getMaxMmsConnections(IedServerConfig self)
{
return self->maxMmsConnections;
}
+
+void
+IedServerConfig_setSyncIntegrityReportTimes(IedServerConfig self, bool enable)
+{
+ self->syncIntegrityReportTimes = enable;
+}
+
+bool
+IedServerConfig_getSyncIntegrityReportTimes(IedServerConfig self)
+{
+ return self->syncIntegrityReportTimes;
+}
diff --git a/src/iec61850/server/mms_mapping/mms_mapping.c b/src/iec61850/server/mms_mapping/mms_mapping.c
index 75a0d7f0..78295db2 100644
--- a/src/iec61850/server/mms_mapping/mms_mapping.c
+++ b/src/iec61850/server/mms_mapping/mms_mapping.c
@@ -2033,6 +2033,12 @@ MmsMapping_create(IedModel* model, IedServer iedServer)
self->settingGroups = LinkedList_create();
#endif
+ self->isModelLocked = false;
+
+#if (CONFIG_MMS_THREADLESS_STACK != 1)
+ self->isModelLockedMutex = Semaphore_create(1);
+#endif
+
self->attributeAccessHandlers = LinkedList_create();
/* create data model specification */
@@ -2123,6 +2129,10 @@ MmsMapping_destroy(MmsMapping* self)
if (self->locbTrk) GLOBAL_FREEMEM(self->locbTrk);
#endif
+#if (CONFIG_MMS_THREADLESS_STACK != 1)
+ Semaphore_destroy(self->isModelLockedMutex);
+#endif
+
LinkedList_destroy(self->attributeAccessHandlers);
IedModel_setAttributeValuesToNull(self->model);
@@ -3665,6 +3675,8 @@ MmsMapping_triggerReportObservers(MmsMapping* self, MmsValue* value, int flag)
{
LinkedList element = self->reportControls;
+ Semaphore_wait(self->isModelLockedMutex);
+
bool modelLocked = self->isModelLocked;
while ((element = LinkedList_getNext(element)) != NULL) {
@@ -3700,6 +3712,8 @@ MmsMapping_triggerReportObservers(MmsMapping* self, MmsValue* value, int flag)
if (modelLocked == false) {
Reporting_processReportEventsAfterUnlock(self);
}
+
+ Semaphore_post(self->isModelLockedMutex);
}
#endif /* (CONFIG_IEC61850_REPORT_SERVICE == 1) */
@@ -3711,8 +3725,6 @@ MmsMapping_triggerGooseObservers(MmsMapping* self, MmsValue* value)
{
LinkedList element = self->gseControls;
- bool modelLocked = self->isModelLocked;
-
while ((element = LinkedList_getNext(element)) != NULL) {
MmsGooseControlBlock gcb = (MmsGooseControlBlock) element->data;
@@ -3722,9 +3734,13 @@ MmsMapping_triggerGooseObservers(MmsMapping* self, MmsValue* value)
if (DataSet_isMemberValue(dataSet, value, NULL)) {
MmsGooseControlBlock_setStateChangePending(gcb);
- if (modelLocked == false) {
+ Semaphore_wait(self->isModelLockedMutex);
+
+ if (self->isModelLocked == false) {
MmsGooseControlBlock_publishNewState(gcb);
}
+
+ Semaphore_post(self->isModelLockedMutex);
}
}
}
diff --git a/src/iec61850/server/mms_mapping/reporting.c b/src/iec61850/server/mms_mapping/reporting.c
index 4bac9847..2526f8fd 100644
--- a/src/iec61850/server/mms_mapping/reporting.c
+++ b/src/iec61850/server/mms_mapping/reporting.c
@@ -929,6 +929,21 @@ refreshTriggerOptions(ReportControl* rc)
#endif
}
+static uint64_t
+getNextRoundedStartTime(uint64_t currentTime, uint64_t intgPd)
+{
+ uint64_t modTime = currentTime % intgPd;
+ uint64_t delta = 0;
+
+ if (modTime != 0) {
+ delta = intgPd - modTime;
+ }
+
+ uint64_t nextTime = currentTime + delta;
+
+ return nextTime;
+}
+
static void
refreshIntegrityPeriod(ReportControl* rc)
{
@@ -943,8 +958,14 @@ refreshIntegrityPeriod(ReportControl* rc)
Semaphore_post(rc->rcbValuesLock);
#endif
- if (rc->buffered == false)
- rc->nextIntgReportTime = Hal_getTimeInMs() + rc->intgPd;
+ if (rc->buffered == false) {
+ if (rc->server->syncIntegrityReportTimes) {
+ rc->nextIntgReportTime = getNextRoundedStartTime(Hal_getTimeInMs(), rc->intgPd);
+ }
+ else {
+ rc->nextIntgReportTime = Hal_getTimeInMs() + rc->intgPd;
+ }
+ }
}
static void
@@ -2128,7 +2149,14 @@ Reporting_RCBWriteAccessHandler(MmsMapping* self, ReportControl* rc, char* eleme
refreshIntegrityPeriod(rc);
if (rc->buffered) {
- rc->nextIntgReportTime = 0;
+
+ if (rc->server->syncIntegrityReportTimes) {
+ rc->nextIntgReportTime = getNextRoundedStartTime(Hal_getTimeInMs(), rc->intgPd);
+ }
+ else {
+ rc->nextIntgReportTime = 0;
+ }
+
purgeBuf(rc);
if (self->rcbEventHandler) {
@@ -3062,10 +3090,6 @@ enqueueReport(ReportControl* reportControl, bool isIntegrity, bool isGI, uint64_
exit_function:
- if (overflow) {
- /* TODO call user callback handler */
- }
-
#if (CONFIG_MMS_THREADLESS_STACK != 1)
Semaphore_post(buffer->lock);
#endif
@@ -3788,7 +3812,13 @@ processEventsForReport(ReportControl* rc, uint64_t currentTimeInMs)
/* check for system time change effects */
if ((rc->nextIntgReportTime < currentTimeInMs) || (rc->nextIntgReportTime > currentTimeInMs + rc->intgPd)) {
- rc->nextIntgReportTime = currentTimeInMs + rc->intgPd;
+
+ if (rc->server->syncIntegrityReportTimes) {
+ rc->nextIntgReportTime = getNextRoundedStartTime(currentTimeInMs, rc->intgPd);
+ }
+ else {
+ rc->nextIntgReportTime = currentTimeInMs + rc->intgPd;
+ }
}
enqueueReport(rc, true, false, currentTimeInMs);
@@ -3798,7 +3828,12 @@ processEventsForReport(ReportControl* rc, uint64_t currentTimeInMs)
else {
/* check for system time change effects */
if ((rc->nextIntgReportTime < currentTimeInMs) || (rc->nextIntgReportTime > currentTimeInMs + rc->intgPd)) {
- rc->nextIntgReportTime = currentTimeInMs + rc->intgPd;
+ if (rc->server->syncIntegrityReportTimes) {
+ rc->nextIntgReportTime = getNextRoundedStartTime(currentTimeInMs, rc->intgPd);
+ }
+ else {
+ rc->nextIntgReportTime = currentTimeInMs + rc->intgPd;
+ }
}
}
@@ -3819,6 +3854,8 @@ processEventsForReport(ReportControl* rc, uint64_t currentTimeInMs)
void
Reporting_processReportEvents(MmsMapping* self, uint64_t currentTimeInMs)
{
+ Semaphore_wait(self->isModelLockedMutex);
+
if (self->isModelLocked == false) {
LinkedList element = self->reportControls;
@@ -3833,6 +3870,8 @@ Reporting_processReportEvents(MmsMapping* self, uint64_t currentTimeInMs)
ReportControl_unlockNotify(rc);
}
}
+
+ Semaphore_post(self->isModelLockedMutex);
}
/*
@@ -4169,6 +4208,8 @@ ReportControlBlock_getGI(ReportControlBlock* self)
bool
ReportControlBlock_getPurgeBuf(ReportControlBlock* self)
{
+ bool purgeBuf = false;
+
if (self->trgOps & 64) {
ReportControl* rc = (ReportControl*)(self->sibling);
@@ -4178,22 +4219,23 @@ ReportControlBlock_getPurgeBuf(ReportControlBlock* self)
MmsValue* purgeBufValue = ReportControl_getRCBValue(rc, "PurgeBuf");
- bool purgeBuf = MmsValue_getBoolean(purgeBufValue);
+ if (purgeBufValue) {
+ purgeBuf = MmsValue_getBoolean(purgeBufValue);
+ }
#if (CONFIG_MMS_THREADLESS_STACK != 1)
Semaphore_post(rc->rcbValuesLock);
#endif
-
- return purgeBuf;
- }
- else {
- return false;
}
+
+ return purgeBuf;
}
MmsValue*
ReportControlBlock_getEntryId(ReportControlBlock* self)
{
+ MmsValue* entryId = NULL;
+
if (self->trgOps & 64) {
ReportControl* rc = (ReportControl*)(self->sibling);
@@ -4203,22 +4245,21 @@ ReportControlBlock_getEntryId(ReportControlBlock* self)
MmsValue* entryIdValue = ReportControl_getRCBValue(rc, "EntryID");
- MmsValue* entryId = MmsValue_clone(entryIdValue);
+ entryId = MmsValue_clone(entryIdValue);
#if (CONFIG_MMS_THREADLESS_STACK != 1)
Semaphore_post(rc->rcbValuesLock);
#endif
-
- return entryId;
- }
- else {
- return NULL;
}
+
+ return entryId;
}
uint64_t
ReportControlBlock_getTimeofEntry(ReportControlBlock* self)
{
+ uint64_t timeofEntry = 0;
+
if (self->trgOps & 64) {
ReportControl* rc = (ReportControl*)(self->sibling);
@@ -4228,22 +4269,23 @@ ReportControlBlock_getTimeofEntry(ReportControlBlock* self)
MmsValue* timeofEntryValue = ReportControl_getRCBValue(rc, "TimeofEntry");
- uint64_t timeofEntry = MmsValue_getBinaryTimeAsUtcMs(timeofEntryValue);
+ if (timeofEntryValue) {
+ timeofEntry = MmsValue_getBinaryTimeAsUtcMs(timeofEntryValue);
+ }
#if (CONFIG_MMS_THREADLESS_STACK != 1)
Semaphore_post(rc->rcbValuesLock);
#endif
-
- return timeofEntry;
- }
- else {
- return 0;
}
+
+ return timeofEntry;
}
int16_t
ReportControlBlock_getResvTms(ReportControlBlock* self)
{
+ int16_t resvTms = 0;
+
if (self->trgOps & 64) {
ReportControl* rc = (ReportControl*)(self->sibling);
@@ -4253,22 +4295,23 @@ ReportControlBlock_getResvTms(ReportControlBlock* self)
MmsValue* resvTmsValue = ReportControl_getRCBValue(rc, "ResvTms");
- int16_t resvTms = (int16_t)MmsValue_toInt32(resvTmsValue);
+ if (resvTmsValue) {
+ resvTms = (int16_t)MmsValue_toInt32(resvTmsValue);
+ }
#if (CONFIG_MMS_THREADLESS_STACK != 1)
Semaphore_post(rc->rcbValuesLock);
#endif
-
- return resvTms;
- }
- else {
- return 0;
}
+
+ return resvTms;
}
bool
ReportControlBlock_getResv(ReportControlBlock* self)
{
+ bool resv = false;
+
if (self->trgOps & 64) {
ReportControl* rc = (ReportControl*)(self->sibling);
@@ -4278,17 +4321,16 @@ ReportControlBlock_getResv(ReportControlBlock* self)
MmsValue* resvValue = ReportControl_getRCBValue(rc, "Resv");
- bool resv = MmsValue_getBoolean(resvValue);
+ if (resvValue) {
+ resv = MmsValue_getBoolean(resvValue);
+ }
#if (CONFIG_MMS_THREADLESS_STACK != 1)
Semaphore_post(rc->rcbValuesLock);
#endif
-
- return resv;
- }
- else {
- return false;
}
+
+ return resv;
}
MmsValue*
diff --git a/tools/model_generator/gendyncode.jar b/tools/model_generator/gendyncode.jar
index 9763ccfb..c982eb0f 100644
Binary files a/tools/model_generator/gendyncode.jar and b/tools/model_generator/gendyncode.jar differ
diff --git a/tools/model_generator/src/com/libiec61850/tools/DynamicCodeGenerator.java b/tools/model_generator/src/com/libiec61850/tools/DynamicCodeGenerator.java
index 2cc6ff00..ccc1bd1d 100644
--- a/tools/model_generator/src/com/libiec61850/tools/DynamicCodeGenerator.java
+++ b/tools/model_generator/src/com/libiec61850/tools/DynamicCodeGenerator.java
@@ -73,6 +73,18 @@ public class DynamicCodeGenerator {
createDynamicCode(sclParser);
}
+
+ private static String replaceInvalidCharacters(String originalStr)
+ {
+ String newString = originalStr;
+
+ newString = newString.replace('/', '_');
+ newString = newString.replace('\\', '_');
+ newString = newString.replace('-', '_');
+ newString = newString.replace('+', '_');
+
+ return newString;
+ }
private static void createDynamicCode(SclParser sclParser) {
TypeDeclarations declarations = sclParser.getTypeDeclarations();
@@ -101,21 +113,21 @@ public class DynamicCodeGenerator {
/* Create function prototypes */
for (LogicalNodeType lnType : lnTypeDefs) {
- String functionPrototype = "LogicalNode*\nLN_" + lnType.getId()
+ String functionPrototype = "LogicalNode*\nLN_" + replaceInvalidCharacters(lnType.getId())
+ "_createInstance(char* lnName, LogicalDevice* parent);";
functionPrototypes.add(functionPrototype);
}
for (DataObjectType doType : doTypeDefs) {
- String functionPrototype = "DataObject*\nDO_" + doType.getId()
+ String functionPrototype = "DataObject*\nDO_" + replaceInvalidCharacters(doType.getId())
+ "_createInstance(char* doName, ModelNode* parent, int arrayCount);";
functionPrototypes.add(functionPrototype);
}
for (DataAttributeType daType : daTypeDefs) {
- String functionPrototype = "DataAttribute*\nDA_" + daType.getId()
+ String functionPrototype = "DataAttribute*\nDA_" + replaceInvalidCharacters(daType.getId())
+ "_createInstance(char* daName, ModelNode* parent, FunctionalConstraint fc, uint8_t triggerOptions);";
functionPrototypes.add(functionPrototype);
@@ -135,19 +147,19 @@ public class DynamicCodeGenerator {
for (LogicalNodeType lnType : lnTypeDefs) {
out.println("/**");
- out.printf(" * LN: %s ", lnType.getId());
+ out.printf(" * LN: %s ", replaceInvalidCharacters(lnType.getId()));
if (lnType.getDesc() != null)
out.printf("(%s)", lnType.getDesc());
out.println();
out.println(" */");
out.println("LogicalNode*");
- out.printf("LN_%s_createInstance(char* lnName, LogicalDevice* parent)\n", lnType.getId());
+ out.printf("LN_%s_createInstance(char* lnName, LogicalDevice* parent)\n", replaceInvalidCharacters(lnType.getId()));
out.println("{");
out.println(" LogicalNode* newLn = LogicalNode_create(lnName, parent);\n");
List doDefs = lnType.getDataObjectDefinitions();
for (DataObjectDefinition objDef : doDefs) {
- out.printf(" DO_%s_createInstance(\"%s\", (ModelNode*) newLn, %d);\n", objDef.getType(), objDef.getName(), objDef.getCount());
+ out.printf(" DO_%s_createInstance(\"%s\", (ModelNode*) newLn, %d);\n", replaceInvalidCharacters(objDef.getType()), objDef.getName(), objDef.getCount());
}
out.println("\n return newLn;");
@@ -156,13 +168,13 @@ public class DynamicCodeGenerator {
for (DataObjectType doType : doTypeDefs) {
out.println("/**");
- out.printf(" * DO: %s ", doType.getId());
+ out.printf(" * DO: %s ", replaceInvalidCharacters(doType.getId()));
if (doType.getDesc() != null)
out.printf("(%s)", doType.getDesc());
out.println();
out.println(" */");
out.println("DataObject*");
- out.printf("DO_%s_createInstance(char* doName, ModelNode* parent, int arrayCount)\n", doType.getId());
+ out.printf("DO_%s_createInstance(char* doName, ModelNode* parent, int arrayCount)\n", replaceInvalidCharacters(doType.getId()));
out.println("{");
out.println(" DataObject* newDo = DataObject_create(doName, parent, arrayCount);\n");
@@ -170,7 +182,7 @@ public class DynamicCodeGenerator {
for (DataAttributeDefinition dad : doType.getDataAttributes()) {
if (dad.getAttributeType() == AttributeType.CONSTRUCTED) {
- out.print(" DA_" + dad.getType() + "_createInstance(\"" + dad.getName() + "\", ");
+ out.print(" DA_" + replaceInvalidCharacters(dad.getType()) + "_createInstance(\"" + dad.getName() + "\", ");
out.print("(ModelNode*) newDo, IEC61850_FC_" + dad.getFc().toString());
out.print(", " + dad.getTriggerOptions().getIntValue());
out.println(");");
@@ -189,7 +201,7 @@ public class DynamicCodeGenerator {
for (DataObjectDefinition dod : doType.getSubDataObjects()) {
- out.print(" DO_" + dod.getType() + "_createInstance(\"" + dod.getName() + "\", ");
+ out.print(" DO_" + replaceInvalidCharacters(dod.getType()) + "_createInstance(\"" + dod.getName() + "\", ");
out.println("(ModelNode*) newDo, " + dod.getCount() + ");");
}
@@ -199,19 +211,19 @@ public class DynamicCodeGenerator {
for (DataAttributeType daType : daTypeDefs) {
out.println("/**");
- out.printf(" * DA: %s ", daType.getId());
+ out.printf(" * DA: %s ", replaceInvalidCharacters(daType.getId()));
if (daType.getDesc() != null)
out.printf("(%s)", daType.getDesc());
out.println();
out.println(" */");
out.println("DataAttribute*");
- out.printf("DA_%s_createInstance(char* daName, ModelNode* parent, FunctionalConstraint fc, uint8_t triggerOptions)\n", daType.getId());
+ out.printf("DA_%s_createInstance(char* daName, ModelNode* parent, FunctionalConstraint fc, uint8_t triggerOptions)\n", replaceInvalidCharacters(daType.getId()));
out.println("{");
out.println(" DataAttribute* newDa = DataAttribute_create(daName, parent, IEC61850_CONSTRUCTED, fc, triggerOptions, 0, 0);\n");
for (DataAttributeDefinition dad : daType.getSubDataAttributes()) {
if (dad.getAttributeType() == AttributeType.CONSTRUCTED) {
- out.print(" DA_" + dad.getType() + "_createInstance(\"" + dad.getName() + "\", ");
+ out.print(" DA_" + replaceInvalidCharacters(dad.getType()) + "_createInstance(\"" + dad.getName() + "\", ");
out.println("(ModelNode*) newDa, fc, triggerOptions);");
}
else {