- IED server: integrated GOOSE publisher - lock data model during GOOSE retransmission to avoid corrupted GOOSE data

pull/320/head
Michael Zillgith 5 years ago
parent 0451460c7e
commit a5f3e79ad1

@ -66,7 +66,7 @@ LIB61850_INTERNAL bool
MmsGooseControlBlock_isEnabled(MmsGooseControlBlock self); MmsGooseControlBlock_isEnabled(MmsGooseControlBlock self);
LIB61850_INTERNAL void LIB61850_INTERNAL void
MmsGooseControlBlock_checkAndPublish(MmsGooseControlBlock self, uint64_t currentTime); MmsGooseControlBlock_checkAndPublish(MmsGooseControlBlock self, uint64_t currentTime, MmsMapping* mapping);
LIB61850_INTERNAL void LIB61850_INTERNAL void
MmsGooseControlBlock_setStateChangePending(MmsGooseControlBlock self); MmsGooseControlBlock_setStateChangePending(MmsGooseControlBlock self);

@ -335,39 +335,50 @@ MmsGooseControlBlock_disable(MmsGooseControlBlock self)
void void
MmsGooseControlBlock_checkAndPublish(MmsGooseControlBlock self, uint64_t currentTime) MmsGooseControlBlock_checkAndPublish(MmsGooseControlBlock self, uint64_t currentTime, MmsMapping* mapping)
{ {
if (currentTime >= self->nextPublishTime) { if (currentTime >= self->nextPublishTime) {
IedServer_lockDataModel(mapping->iedServer);
if (currentTime >= self->nextPublishTime) {
#if (CONFIG_MMS_THREADLESS_STACK != 1) #if (CONFIG_MMS_THREADLESS_STACK != 1)
Semaphore_wait(self->publisherMutex); Semaphore_wait(self->publisherMutex);
#endif #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) { if (self->retransmissionsLeft > 0) {
self->nextPublishTime = currentTime + self->minTime; 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) self->retransmissionsLeft--;
GoosePublisher_setTimeAllowedToLive(self->publisher, self->minTime * 3); }
else else {
GoosePublisher_setTimeAllowedToLive(self->publisher, self->maxTime * 3); 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) #if (CONFIG_MMS_THREADLESS_STACK != 1)
Semaphore_post(self->publisherMutex); Semaphore_post(self->publisherMutex);
#endif #endif
} }
else if ((self->nextPublishTime - currentTime) > ((uint32_t) self->maxTime * 2)) {
self->nextPublishTime = currentTime + self->minTime; IedServer_unlockDataModel(mapping->iedServer);
}
else if ((self->nextPublishTime - currentTime) > ((uint32_t) self->maxTime * 2)) {
self->nextPublishTime = currentTime + self->minTime;
}
} }
} }

@ -3015,7 +3015,7 @@ GOOSE_processGooseEvents(MmsMapping* self, uint64_t currentTimeInMs)
MmsGooseControlBlock mmsGCB = (MmsGooseControlBlock) element->data; MmsGooseControlBlock mmsGCB = (MmsGooseControlBlock) element->data;
if (MmsGooseControlBlock_isEnabled(mmsGCB)) { if (MmsGooseControlBlock_isEnabled(mmsGCB)) {
MmsGooseControlBlock_checkAndPublish(mmsGCB, currentTimeInMs); MmsGooseControlBlock_checkAndPublish(mmsGCB, currentTimeInMs, self);
} }
element = LinkedList_getNext(element); element = LinkedList_getNext(element);

Loading…
Cancel
Save