From 4e15343f5b7d0a6e1af3fb16175fb909601f39fb Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Tue, 9 Mar 2021 17:11:20 +0100 Subject: [PATCH] - IED server: integrated GOOSE publisher - lock data model during GOOSE retransmission to avoid corrupted GOOSE data --- src/iec61850/inc_private/mms_goose.h | 2 +- src/iec61850/server/mms_mapping/mms_goose.c | 40 +++++++++++-------- src/iec61850/server/mms_mapping/mms_mapping.c | 2 +- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/iec61850/inc_private/mms_goose.h b/src/iec61850/inc_private/mms_goose.h index e2c6f93f..65faa077 100644 --- a/src/iec61850/inc_private/mms_goose.h +++ b/src/iec61850/inc_private/mms_goose.h @@ -55,7 +55,7 @@ LIB61850_INTERNAL bool MmsGooseControlBlock_isEnabled(MmsGooseControlBlock self); LIB61850_INTERNAL void -MmsGooseControlBlock_checkAndPublish(MmsGooseControlBlock self, uint64_t currentTime); +MmsGooseControlBlock_checkAndPublish(MmsGooseControlBlock self, uint64_t currentTime, MmsMapping* mapping); LIB61850_INTERNAL void MmsGooseControlBlock_setStateChangePending(MmsGooseControlBlock self); diff --git a/src/iec61850/server/mms_mapping/mms_goose.c b/src/iec61850/server/mms_mapping/mms_goose.c index 730bbfff..d33c0ece 100644 --- a/src/iec61850/server/mms_mapping/mms_goose.c +++ b/src/iec61850/server/mms_mapping/mms_goose.c @@ -506,37 +506,45 @@ MmsGooseControlBlock_disable(MmsGooseControlBlock self, MmsMapping* mmsMapping) void -MmsGooseControlBlock_checkAndPublish(MmsGooseControlBlock self, uint64_t currentTime) +MmsGooseControlBlock_checkAndPublish(MmsGooseControlBlock self, uint64_t currentTime, MmsMapping* mapping) { if (self->publisher) { if (currentTime >= self->nextPublishTime) { + IedServer_lockDataModel(mapping->iedServer); + + if (currentTime >= self->nextPublishTime) { + #if (CONFIG_MMS_THREADLESS_STACK != 1) - Semaphore_wait(self->publisherMutex); + Semaphore_wait(self->publisherMutex); #endif - GoosePublisher_publish(self->publisher, self->dataSetValues); + GoosePublisher_publish(self->publisher, self->dataSetValues); - if (self->retransmissionsLeft > 0) { - self->nextPublishTime = currentTime + self->minTime; + if (self->retransmissionsLeft > 0) { + self->nextPublishTime = currentTime + self->minTime; - if (self->retransmissionsLeft > 1) - GoosePublisher_setTimeAllowedToLive(self->publisher, self->minTime * 3); - else - GoosePublisher_setTimeAllowedToLive(self->publisher, self->maxTime * 3); + if (self->retransmissionsLeft > 1) + GoosePublisher_setTimeAllowedToLive(self->publisher, self->minTime * 3); + else + GoosePublisher_setTimeAllowedToLive(self->publisher, self->maxTime * 3); - self->retransmissionsLeft--; - } - else { - GoosePublisher_setTimeAllowedToLive(self->publisher, self->maxTime * 3); + self->retransmissionsLeft--; + } + else { + GoosePublisher_setTimeAllowedToLive(self->publisher, self->maxTime * 3); - self->nextPublishTime = currentTime + self->maxTime; - } + self->nextPublishTime = currentTime + self->maxTime; + } #if (CONFIG_MMS_THREADLESS_STACK != 1) - Semaphore_post(self->publisherMutex); + Semaphore_post(self->publisherMutex); #endif + } + + IedServer_unlockDataModel(mapping->iedServer); + } else if ((self->nextPublishTime - currentTime) > ((uint32_t) self->maxTime * 2)) { self->nextPublishTime = currentTime + self->minTime; diff --git a/src/iec61850/server/mms_mapping/mms_mapping.c b/src/iec61850/server/mms_mapping/mms_mapping.c index 01898f18..32471c8f 100644 --- a/src/iec61850/server/mms_mapping/mms_mapping.c +++ b/src/iec61850/server/mms_mapping/mms_mapping.c @@ -3748,7 +3748,7 @@ GOOSE_processGooseEvents(MmsMapping* self, uint64_t currentTimeInMs) MmsGooseControlBlock mmsGCB = (MmsGooseControlBlock) element->data; if (MmsGooseControlBlock_isEnabled(mmsGCB)) { - MmsGooseControlBlock_checkAndPublish(mmsGCB, currentTimeInMs); + MmsGooseControlBlock_checkAndPublish(mmsGCB, currentTimeInMs, self); } element = LinkedList_getNext(element);