From a4fdf089bb5c2b8e6884a9f1699aaeb54244adff Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Thu, 2 Jun 2022 00:37:31 +0200 Subject: [PATCH] - fixed locking mechanism in logging.c (LIB61850-327) --- src/iec61850/inc_private/logging.h | 6 +- src/iec61850/server/mms_mapping/logging.c | 70 +++++++++++-------- src/iec61850/server/mms_mapping/mms_mapping.c | 24 ++++--- 3 files changed, 59 insertions(+), 41 deletions(-) diff --git a/src/iec61850/inc_private/logging.h b/src/iec61850/inc_private/logging.h index 74caf056..7684739a 100644 --- a/src/iec61850/inc_private/logging.h +++ b/src/iec61850/inc_private/logging.h @@ -1,7 +1,7 @@ /* * logging.h * - * Copyright 2016 Michael Zillgith + * Copyright 2016-2022 Michael Zillgith * * This file is part of libIEC61850. * @@ -29,7 +29,9 @@ typedef struct { char* name; LogicalNode* parentLN; - bool locked; +#if (CONFIG_MMS_THREADLESS_STACK != 1) + Semaphore lock; +#endif LogStorage logStorage; diff --git a/src/iec61850/server/mms_mapping/logging.c b/src/iec61850/server/mms_mapping/logging.c index 97d627ff..f047fc0d 100644 --- a/src/iec61850/server/mms_mapping/logging.c +++ b/src/iec61850/server/mms_mapping/logging.c @@ -52,7 +52,10 @@ LogInstance_create(LogicalNode* parentLN, const char* name) self->name = StringUtils_copyString(name); self->parentLN = parentLN; self->logStorage = NULL; - self->locked = false; + +#if (CONFIG_MMS_THREADLESS_STACK != 1) + self->lock = Semaphore_create(1); +#endif self->oldEntryId = 0; self->oldEntryTime = 0; @@ -67,6 +70,10 @@ void LogInstance_destroy(LogInstance* self) { if (self) { +#if (CONFIG_MMS_THREADLESS_STACK != 1) + Semaphore_destroy(self->lock); +#endif + GLOBAL_FREEMEM(self->name); GLOBAL_FREEMEM(self); } @@ -79,10 +86,9 @@ LogInstance_logSingleData(LogInstance* self, const char* dataRef, MmsValue* valu if (logStorage != NULL) { - while (self->locked) - Thread_sleep(1); - - self->locked = true; +#if (CONFIG_MMS_THREADLESS_STACK != 1) + Semaphore_wait(self->lock); +#endif if (DEBUG_IED_SERVER) printf("IED_SERVER: Log value - dataRef: %s flag: %i\n", dataRef, flag); @@ -95,17 +101,21 @@ LogInstance_logSingleData(LogInstance* self, const char* dataRef, MmsValue* valu uint8_t* data = (uint8_t*) GLOBAL_MALLOC(dataSize); - MmsValue_encodeMmsData(value, data, 0, true); - - LogStorage_addEntryData(logStorage, entryID, dataRef, data, dataSize, flag); + if (data) { + MmsValue_encodeMmsData(value, data, 0, true); - self->locked = false; + LogStorage_addEntryData(logStorage, entryID, dataRef, data, dataSize, flag); - GLOBAL_FREEMEM(data); + GLOBAL_FREEMEM(data); + } self->newEntryId = entryID; self->newEntryTime = timestamp; +#if (CONFIG_MMS_THREADLESS_STACK != 1) + Semaphore_post(self->lock); +#endif + } else if (DEBUG_IED_SERVER) @@ -119,10 +129,9 @@ LogInstance_logEntryStart(LogInstance* self) if (logStorage != NULL) { - while (self->locked) - Thread_sleep(1); - - self->locked = true; +#if (CONFIG_MMS_THREADLESS_STACK != 1) + Semaphore_wait(self->lock); +#endif uint64_t timestamp = Hal_getTimeInMs(); @@ -143,19 +152,19 @@ LogInstance_logEntryData(LogInstance* self, uint64_t entryID, const char* dataRe { LogStorage logStorage = self->logStorage; - if (logStorage != NULL) { + if (logStorage) { int dataSize = MmsValue_encodeMmsData(value, NULL, 0, false); uint8_t* data = (uint8_t*) GLOBAL_MALLOC(dataSize); - MmsValue_encodeMmsData(value, data, 0, true); + if (data) { + MmsValue_encodeMmsData(value, data, 0, true); - LogStorage_addEntryData(logStorage, entryID, dataRef, data, dataSize, flag); + LogStorage_addEntryData(logStorage, entryID, dataRef, data, dataSize, flag); - self->locked = false; - - GLOBAL_FREEMEM(data); + GLOBAL_FREEMEM(data); + } } } @@ -164,7 +173,9 @@ LogInstance_logEntryFinished(LogInstance* self, uint64_t entryID) { (void)entryID; - self->locked = false; +#if (CONFIG_MMS_THREADLESS_STACK != 1) + Semaphore_post(self->lock); +#endif } void @@ -989,18 +1000,21 @@ LogControl_logAllDatasetEntries(LogControl* self, const char* iedName) uint64_t entryID = LogInstance_logEntryStart(log); - DataSetEntry* dataSetEntry = self->dataSet->fcdas; + if (entryID != 0) { - while (dataSetEntry != NULL) { + DataSetEntry* dataSetEntry = self->dataSet->fcdas; - sprintf(dataRef, "%s%s/%s", iedName, dataSetEntry->logicalDeviceName, dataSetEntry->variableName); + while (dataSetEntry != NULL) { - LogInstance_logEntryData(log, entryID, dataRef, dataSetEntry->value, TRG_OPT_INTEGRITY * 2); + sprintf(dataRef, "%s%s/%s", iedName, dataSetEntry->logicalDeviceName, dataSetEntry->variableName); - dataSetEntry = dataSetEntry->sibling; - } + LogInstance_logEntryData(log, entryID, dataRef, dataSetEntry->value, TRG_OPT_INTEGRITY * 2); - LogInstance_logEntryFinished(log, entryID); + dataSetEntry = dataSetEntry->sibling; + } + + LogInstance_logEntryFinished(log, entryID); + } } } diff --git a/src/iec61850/server/mms_mapping/mms_mapping.c b/src/iec61850/server/mms_mapping/mms_mapping.c index 23145aa4..75a0d7f0 100644 --- a/src/iec61850/server/mms_mapping/mms_mapping.c +++ b/src/iec61850/server/mms_mapping/mms_mapping.c @@ -1344,21 +1344,23 @@ checkForServiceTrackingVariables(MmsMapping* self, LogicalNode* logicalNode) else if (!strcmp(modelNode->name, "BacTrk")) actInstance = &self->bacTrk; - if (*actInstance != NULL) { - if (DEBUG_IED_SERVER) - printf("IED_SERVER: ERROR: multiple %s instances found in server\n", modelNode->name); - } - else { - *actInstance = (ControlTrkInstance) GLOBAL_CALLOC(1, sizeof(struct sControlTrkInstance)); - + if (actInstance) + { if (*actInstance != NULL) { - (*actInstance)->dobj = actTrk; + if (DEBUG_IED_SERVER) + printf("IED_SERVER: ERROR: multiple %s instances found in server\n", modelNode->name); + } + else { + *actInstance = (ControlTrkInstance) GLOBAL_CALLOC(1, sizeof(struct sControlTrkInstance)); + + if (*actInstance != NULL) { + (*actInstance)->dobj = actTrk; - getCommonTrackingAttributes((ServiceTrkInstance) *actInstance, actTrk); - getControlTrackingAttributes(*actInstance, actTrk); + getCommonTrackingAttributes((ServiceTrkInstance) *actInstance, actTrk); + getControlTrackingAttributes(*actInstance, actTrk); + } } } - } else if (!strcmp(modelNode->name, "BrcbTrk")) { if (DEBUG_IED_SERVER)