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/src/iec61850/inc/iec61850_server.h b/src/iec61850/inc/iec61850_server.h index 48c79533..670f5c85 100644 --- a/src/iec61850/inc/iec61850_server.h +++ b/src/iec61850/inc/iec61850_server.h @@ -1549,7 +1549,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/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 6534fb7b..9d750ddf 100644 --- a/src/iec61850/server/impl/ied_server.c +++ b/src/iec61850/server/impl/ied_server.c @@ -811,9 +811,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 @@ -827,9 +831,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/mms_mapping/mms_mapping.c b/src/iec61850/server/mms_mapping/mms_mapping.c index ff7a490f..5608edb8 100644 --- a/src/iec61850/server/mms_mapping/mms_mapping.c +++ b/src/iec61850/server/mms_mapping/mms_mapping.c @@ -2029,6 +2029,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 */ @@ -2119,6 +2125,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); @@ -3654,6 +3664,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) { @@ -3689,6 +3701,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) */ @@ -3700,8 +3714,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; @@ -3711,9 +3723,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 91f1c004..27dd05fc 100644 --- a/src/iec61850/server/mms_mapping/reporting.c +++ b/src/iec61850/server/mms_mapping/reporting.c @@ -3062,10 +3062,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 @@ -3819,6 +3815,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 +3831,8 @@ Reporting_processReportEvents(MmsMapping* self, uint64_t currentTimeInMs) ReportControl_unlockNotify(rc); } } + + Semaphore_post(self->isModelLockedMutex); } /*