- added null pointer protection to some constructors/destructors

pull/375/head
Michael Zillgith 4 years ago
parent 8aa988068c
commit 398b14e65f

@ -1,7 +1,7 @@
/* /*
* goose_publisher.c * goose_publisher.c
* *
* Copyright 2013-2018 Michael Zillgith * Copyright 2013-2022 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -91,25 +91,27 @@ GoosePublisher_create(CommParameters* parameters, const char* interfaceID)
void void
GoosePublisher_destroy(GoosePublisher self) GoosePublisher_destroy(GoosePublisher self)
{ {
if (self->ethernetSocket) { if (self) {
Ethernet_destroySocket(self->ethernetSocket); if (self->ethernetSocket) {
} Ethernet_destroySocket(self->ethernetSocket);
}
MmsValue_delete(self->timestamp); MmsValue_delete(self->timestamp);
if (self->goID != NULL) if (self->goID != NULL)
GLOBAL_FREEMEM(self->goID); GLOBAL_FREEMEM(self->goID);
if (self->goCBRef != NULL) if (self->goCBRef != NULL)
GLOBAL_FREEMEM(self->goCBRef); GLOBAL_FREEMEM(self->goCBRef);
if (self->dataSetRef != NULL) if (self->dataSetRef != NULL)
GLOBAL_FREEMEM(self->dataSetRef); GLOBAL_FREEMEM(self->dataSetRef);
if (self->buffer) if (self->buffer)
GLOBAL_FREEMEM(self->buffer); GLOBAL_FREEMEM(self->buffer);
GLOBAL_FREEMEM(self); GLOBAL_FREEMEM(self);
}
} }
void void

@ -1,7 +1,7 @@
/* /*
* goose_receiver.c * goose_receiver.c
* *
* Copyright 2014-2017 Michael Zillgith * Copyright 2014-2022 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -1014,19 +1014,21 @@ GooseReceiver_stop(GooseReceiver self)
void void
GooseReceiver_destroy(GooseReceiver self) GooseReceiver_destroy(GooseReceiver self)
{ {
if (self) {
#if (CONFIG_MMS_THREADLESS_STACK == 0) #if (CONFIG_MMS_THREADLESS_STACK == 0)
if ((self->thread != NULL) && (GooseReceiver_isRunning(self))) if ((self->thread != NULL) && (GooseReceiver_isRunning(self)))
GooseReceiver_stop(self); GooseReceiver_stop(self);
#endif #endif
if (self->interfaceId != NULL) if (self->interfaceId != NULL)
GLOBAL_FREEMEM(self->interfaceId); GLOBAL_FREEMEM(self->interfaceId);
LinkedList_destroyDeep(self->subscriberList, LinkedList_destroyDeep(self->subscriberList,
(LinkedListValueDeleteFunction) GooseSubscriber_destroy); (LinkedListValueDeleteFunction) GooseSubscriber_destroy);
GLOBAL_FREEMEM(self->buffer); GLOBAL_FREEMEM(self->buffer);
GLOBAL_FREEMEM(self); GLOBAL_FREEMEM(self);
}
} }
/*************************************** /***************************************

@ -1,7 +1,7 @@
/* /*
* goose_subscriber.c * goose_subscriber.c
* *
* Copyright 2013, 2014 Michael Zillgith * Copyright 2013-2022 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -40,24 +40,26 @@ GooseSubscriber_create(char* goCbRef, MmsValue* dataSetValues)
{ {
GooseSubscriber self = (GooseSubscriber) GLOBAL_CALLOC(1, sizeof(struct sGooseSubscriber)); GooseSubscriber self = (GooseSubscriber) GLOBAL_CALLOC(1, sizeof(struct sGooseSubscriber));
strncpy(self->goCBRef, goCbRef, 129); if (self) {
self->goCBRef[129] = 0; strncpy(self->goCBRef, goCbRef, 129);
self->goCBRef[129] = 0;
self->goCBRefLen = strlen(goCbRef); self->goCBRefLen = strlen(goCbRef);
self->timestamp = MmsValue_newUtcTime(0); self->timestamp = MmsValue_newUtcTime(0);
self->dataSetValues = dataSetValues; self->dataSetValues = dataSetValues;
if (dataSetValues) if (dataSetValues)
self->dataSetValuesSelfAllocated = false; self->dataSetValuesSelfAllocated = false;
else else
self->dataSetValuesSelfAllocated = true; self->dataSetValuesSelfAllocated = true;
memset(self->dstMac, 0xFF, 6); memset(self->dstMac, 0xFF, 6);
self->dstMacSet = false; self->dstMacSet = false;
self->appId = -1; self->appId = -1;
self->isObserver = false; self->isObserver = false;
self->vlanSet = false; self->vlanSet = false;
self->parseError = GOOSE_PARSE_ERROR_NO_ERROR; self->parseError = GOOSE_PARSE_ERROR_NO_ERROR;
}
return self; return self;
} }
@ -96,12 +98,14 @@ GooseSubscriber_setAppId(GooseSubscriber self, uint16_t appId)
void void
GooseSubscriber_destroy(GooseSubscriber self) GooseSubscriber_destroy(GooseSubscriber self)
{ {
MmsValue_delete(self->timestamp); if (self) {
MmsValue_delete(self->timestamp);
if (self->dataSetValuesSelfAllocated) if (self->dataSetValuesSelfAllocated)
MmsValue_delete(self->dataSetValues); MmsValue_delete(self->dataSetValues);
GLOBAL_FREEMEM(self); GLOBAL_FREEMEM(self);
}
} }
void void

@ -1,7 +1,7 @@
/* /*
* client_connection.c * client_connection.c
* *
* Copyright 2013, 2014, 2015 Michael Zillgith * Copyright 2013-2022 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -47,12 +47,14 @@ private_ClientConnection_create(void* serverConnectionHandle)
{ {
ClientConnection self = (ClientConnection) GLOBAL_MALLOC(sizeof(struct sClientConnection)); ClientConnection self = (ClientConnection) GLOBAL_MALLOC(sizeof(struct sClientConnection));
if (self) {
#if (CONFIG_MMS_THREADLESS_STACK != 1) #if (CONFIG_MMS_THREADLESS_STACK != 1)
self->tasksCountMutex = Semaphore_create(1); self->tasksCountMutex = Semaphore_create(1);
#endif #endif
self->tasksCount = 0; self->tasksCount = 0;
self->serverConnectionHandle = serverConnectionHandle; self->serverConnectionHandle = serverConnectionHandle;
}
return self; return self;
} }
@ -60,11 +62,13 @@ private_ClientConnection_create(void* serverConnectionHandle)
void void
private_ClientConnection_destroy(ClientConnection self) private_ClientConnection_destroy(ClientConnection self)
{ {
if (self) {
#if (CONFIG_MMS_THREADLESS_STACK != 1) #if (CONFIG_MMS_THREADLESS_STACK != 1)
Semaphore_destroy(self->tasksCountMutex); Semaphore_destroy(self->tasksCountMutex);
#endif #endif
GLOBAL_FREEMEM(self); GLOBAL_FREEMEM(self);
}
} }
int int

@ -1,7 +1,7 @@
/* /*
* ied_server.c * ied_server.c
* *
* Copyright 2013-2020 Michael Zillgith * Copyright 2013-2022 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -594,51 +594,52 @@ IedServer_setRCBEventHandler(IedServer self, IedServer_RCBEventHandler handler,
void void
IedServer_destroy(IedServer self) IedServer_destroy(IedServer self)
{ {
if (self) {
/* Stop server if running */ /* Stop server if running */
if (self->running) { if (self->running) {
#if (CONFIG_MMS_THREADLESS_STACK == 1) #if (CONFIG_MMS_THREADLESS_STACK == 1)
IedServer_stopThreadless(self); IedServer_stopThreadless(self);
#else #else
IedServer_stop(self); IedServer_stop(self);
#endif #endif
} }
#if ((CONFIG_MMS_SINGLE_THREADED == 1) && (CONFIG_MMS_THREADLESS_STACK == 0)) #if ((CONFIG_MMS_SINGLE_THREADED == 1) && (CONFIG_MMS_THREADLESS_STACK == 0))
if (self->serverThread) if (self->serverThread)
Thread_destroy(self->serverThread); Thread_destroy(self->serverThread);
#endif #endif
MmsServer_destroy(self->mmsServer); MmsServer_destroy(self->mmsServer);
if (self->localIpAddress != NULL) if (self->localIpAddress != NULL)
GLOBAL_FREEMEM(self->localIpAddress); GLOBAL_FREEMEM(self->localIpAddress);
if (self->mmsMapping) if (self->mmsMapping)
MmsMapping_destroy(self->mmsMapping); MmsMapping_destroy(self->mmsMapping);
LinkedList_destroyDeep(self->clientConnections, (LinkedListValueDeleteFunction) private_ClientConnection_destroy); LinkedList_destroyDeep(self->clientConnections, (LinkedListValueDeleteFunction) private_ClientConnection_destroy);
#if (CONFIG_MMS_THREADLESS_STACK != 1) #if (CONFIG_MMS_THREADLESS_STACK != 1)
Semaphore_destroy(self->dataModelLock); Semaphore_destroy(self->dataModelLock);
Semaphore_destroy(self->clientConnectionsLock); Semaphore_destroy(self->clientConnectionsLock);
#endif #endif
#if (CONFIG_IEC61850_SUPPORT_SERVER_IDENTITY == 1) #if (CONFIG_IEC61850_SUPPORT_SERVER_IDENTITY == 1)
if (self->vendorName) if (self->vendorName)
GLOBAL_FREEMEM(self->vendorName); GLOBAL_FREEMEM(self->vendorName);
if (self->modelName) if (self->modelName)
GLOBAL_FREEMEM(self->modelName); GLOBAL_FREEMEM(self->modelName);
if (self->revision) if (self->revision)
GLOBAL_FREEMEM(self->revision); GLOBAL_FREEMEM(self->revision);
#endif /* (CONFIG_IEC61850_SUPPORT_SERVER_IDENTITY == 1) */ #endif /* (CONFIG_IEC61850_SUPPORT_SERVER_IDENTITY == 1) */
GLOBAL_FREEMEM(self); GLOBAL_FREEMEM(self);
}
} }
void void

@ -1,7 +1,7 @@
/* /*
* ied_server_config.c * ied_server_config.c
* *
* Copyright 2018-2020 Michael Zillgith * Copyright 2018-2022 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -65,8 +65,10 @@ IedServerConfig_create()
void void
IedServerConfig_destroy(IedServerConfig self) IedServerConfig_destroy(IedServerConfig self)
{ {
GLOBAL_FREEMEM(self->fileServiceBasepath); if (self) {
GLOBAL_FREEMEM(self); GLOBAL_FREEMEM(self->fileServiceBasepath);
GLOBAL_FREEMEM(self);
}
} }
void void

@ -1,7 +1,7 @@
/* /*
* control.c * control.c
* *
* Copyright 2013-2021 Michael Zillgith * Copyright 2013-2022 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -1254,36 +1254,38 @@ ControlObject_handlePendingEvents(ControlObject* self)
void void
ControlObject_destroy(ControlObject* self) ControlObject_destroy(ControlObject* self)
{ {
if (self->mmsValue) if (self) {
MmsValue_delete(self->mmsValue); if (self->mmsValue)
MmsValue_delete(self->mmsValue);
if (self->error) if (self->error)
MmsValue_delete(self->error); MmsValue_delete(self->error);
if (self->addCause) if (self->addCause)
MmsValue_delete(self->addCause); MmsValue_delete(self->addCause);
if (self->ctlVal) if (self->ctlVal)
MmsValue_delete(self->ctlVal); MmsValue_delete(self->ctlVal);
if (self->ctlNum) if (self->ctlNum)
MmsValue_delete(self->ctlNum); MmsValue_delete(self->ctlNum);
if (self->origin) if (self->origin)
MmsValue_delete(self->origin); MmsValue_delete(self->origin);
if (self->name) if (self->name)
GLOBAL_FREEMEM(self->name); GLOBAL_FREEMEM(self->name);
#if (CONFIG_MMS_THREADLESS_STACK != 1) #if (CONFIG_MMS_THREADLESS_STACK != 1)
if (self->stateLock) if (self->stateLock)
Semaphore_destroy(self->stateLock); Semaphore_destroy(self->stateLock);
if (self->pendingEventsLock) if (self->pendingEventsLock)
Semaphore_destroy(self->pendingEventsLock); Semaphore_destroy(self->pendingEventsLock);
#endif #endif
GLOBAL_FREEMEM(self); GLOBAL_FREEMEM(self);
}
} }
char* char*

@ -1,7 +1,7 @@
/* /*
* logging.c * logging.c
* *
* Copyright 2016 Michael Zillgith * Copyright 2016-2022 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -48,15 +48,17 @@ LogInstance_create(LogicalNode* parentLN, const char* name)
{ {
LogInstance* self = (LogInstance*) GLOBAL_MALLOC(sizeof(LogInstance)); LogInstance* self = (LogInstance*) GLOBAL_MALLOC(sizeof(LogInstance));
self->name = StringUtils_copyString(name); if (self) {
self->parentLN = parentLN; self->name = StringUtils_copyString(name);
self->logStorage = NULL; self->parentLN = parentLN;
self->locked = false; self->logStorage = NULL;
self->locked = false;
self->oldEntryId = 0; self->oldEntryId = 0;
self->oldEntryTime = 0; self->oldEntryTime = 0;
self->newEntryId = 0; self->newEntryId = 0;
self->newEntryTime = 0; self->newEntryTime = 0;
}
return self; return self;
} }
@ -64,8 +66,10 @@ LogInstance_create(LogicalNode* parentLN, const char* name)
void void
LogInstance_destroy(LogInstance* self) LogInstance_destroy(LogInstance* self)
{ {
GLOBAL_FREEMEM(self->name); if (self) {
GLOBAL_FREEMEM(self); GLOBAL_FREEMEM(self->name);
GLOBAL_FREEMEM(self);
}
} }
void void
@ -185,17 +189,19 @@ LogControl_create(LogicalNode* parentLN, MmsMapping* mmsMapping)
{ {
LogControl* self = (LogControl*) GLOBAL_MALLOC(sizeof(LogControl)); LogControl* self = (LogControl*) GLOBAL_MALLOC(sizeof(LogControl));
self->enabled = false; if (self) {
self->dataSet = NULL; self->enabled = false;
self->isDynamicDataSet = false; self->dataSet = NULL;
self->triggerOps = 0; self->isDynamicDataSet = false;
self->logicalNode = parentLN; self->triggerOps = 0;
self->mmsMapping = mmsMapping; self->logicalNode = parentLN;
self->dataSetRef = NULL; self->mmsMapping = mmsMapping;
self->logInstance = NULL; self->dataSetRef = NULL;
self->intgPd = 0; self->logInstance = NULL;
self->nextIntegrityScan = 0; self->intgPd = 0;
self->logRef = NULL; self->nextIntegrityScan = 0;
self->logRef = NULL;
}
return self; return self;
} }

@ -274,39 +274,42 @@ MmsGooseControlBlock_create()
void void
MmsGooseControlBlock_destroy(MmsGooseControlBlock self) MmsGooseControlBlock_destroy(MmsGooseControlBlock self)
{ {
if (self) {
#if (CONFIG_MMS_THREADLESS_STACK != 1) #if (CONFIG_MMS_THREADLESS_STACK != 1)
Semaphore_destroy(self->publisherMutex); Semaphore_destroy(self->publisherMutex);
#endif #endif
if (self->publisher != NULL) if (self->publisher != NULL)
GoosePublisher_destroy(self->publisher); GoosePublisher_destroy(self->publisher);
if (self->dataSetValues != NULL) if (self->dataSetValues != NULL)
LinkedList_destroyStatic(self->dataSetValues); LinkedList_destroyStatic(self->dataSetValues);
if (self->goCBRef != NULL) if (self->goCBRef != NULL)
GLOBAL_FREEMEM(self->goCBRef); GLOBAL_FREEMEM(self->goCBRef);
if (self->goId != NULL) if (self->goId != NULL)
GLOBAL_FREEMEM(self->goId); GLOBAL_FREEMEM(self->goId);
if (self->dataSetRef != NULL) if (self->dataSetRef != NULL)
GLOBAL_FREEMEM(self->dataSetRef); GLOBAL_FREEMEM(self->dataSetRef);
if (self->dataSet != NULL) { if (self->dataSet != NULL) {
if (self->isDynamicDataSet) { if (self->isDynamicDataSet) {
MmsMapping_freeDynamicallyCreatedDataSet(self->dataSet); MmsMapping_freeDynamicallyCreatedDataSet(self->dataSet);
self->isDynamicDataSet = false; self->isDynamicDataSet = false;
self->dataSet = NULL; self->dataSet = NULL;
}
} }
}
if (self->gooseInterfaceId != NULL) if (self->gooseInterfaceId != NULL)
GLOBAL_FREEMEM(self->gooseInterfaceId); GLOBAL_FREEMEM(self->gooseInterfaceId);
MmsValue_delete(self->mmsValue); MmsValue_delete(self->mmsValue);
GLOBAL_FREEMEM(self); GLOBAL_FREEMEM(self);
}
} }
void void

@ -1,7 +1,7 @@
/* /*
* mms_sv.c * mms_sv.c
* *
* Copyright 2015 Michael Zillgith * Copyright 2015-2022 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -67,9 +67,11 @@ MmsSampledValueControlBlock_create()
void void
MmsSampledValueControlBlock_destroy(MmsSampledValueControlBlock self) MmsSampledValueControlBlock_destroy(MmsSampledValueControlBlock self)
{ {
MmsValue_delete(self->mmsValue); if (self) {
MmsValue_delete(self->mmsValue);
GLOBAL_FREEMEM(self); GLOBAL_FREEMEM(self);
}
} }
static MmsSampledValueControlBlock static MmsSampledValueControlBlock

@ -84,63 +84,68 @@ ReportBuffer_create(int bufferSize)
static void static void
ReportBuffer_destroy(ReportBuffer* self) ReportBuffer_destroy(ReportBuffer* self)
{ {
GLOBAL_FREEMEM(self->memoryBlock); if (self) {
GLOBAL_FREEMEM(self->memoryBlock);
#if (CONFIG_MMS_THREADLESS_STACK != 1) #if (CONFIG_MMS_THREADLESS_STACK != 1)
Semaphore_destroy(self->lock); Semaphore_destroy(self->lock);
#endif #endif
GLOBAL_FREEMEM(self); GLOBAL_FREEMEM(self);
}
} }
ReportControl* ReportControl*
ReportControl_create(bool buffered, LogicalNode* parentLN, int reportBufferSize, IedServer iedServer) ReportControl_create(bool buffered, LogicalNode* parentLN, int reportBufferSize, IedServer iedServer)
{ {
ReportControl* self = (ReportControl*) GLOBAL_MALLOC(sizeof(ReportControl)); ReportControl* self = (ReportControl*) GLOBAL_MALLOC(sizeof(ReportControl));
self->name = NULL;
self->domain = NULL; if (self) {
self->parentLN = parentLN; self->name = NULL;
self->rcbValues = NULL; self->domain = NULL;
self->parentLN = parentLN;
self->rcbValues = NULL;
#if (CONFIG_MMS_THREADLESS_STACK != 1) #if (CONFIG_MMS_THREADLESS_STACK != 1)
self->rcbValuesLock = Semaphore_create(1); self->rcbValuesLock = Semaphore_create(1);
#endif #endif
self->subSeqVal = MmsValue_newUnsigned(16); self->subSeqVal = MmsValue_newUnsigned(16);
self->segmented = false; self->segmented = false;
self->startIndexForNextSegment = 0; self->startIndexForNextSegment = 0;
self->enabled = false; self->enabled = false;
self->reserved = false; self->reserved = false;
self->buffered = buffered; self->buffered = buffered;
self->isBuffering = false; self->isBuffering = false;
self->isResync = false; self->isResync = false;
self->gi = false; self->gi = false;
self->inclusionField = NULL; self->inclusionField = NULL;
self->dataSet = NULL; self->dataSet = NULL;
self->isDynamicDataSet = false; self->isDynamicDataSet = false;
self->clientConnection = NULL; self->clientConnection = NULL;
self->intgPd = 0; self->intgPd = 0;
self->sqNum = 0; self->sqNum = 0;
self->nextIntgReportTime = 0; self->nextIntgReportTime = 0;
self->inclusionFlags = NULL; self->inclusionFlags = NULL;
self->triggered = false; self->triggered = false;
self->timeOfEntry = NULL; self->timeOfEntry = NULL;
self->reservationTimeout = 0; self->reservationTimeout = 0;
self->triggerOps = 0; self->triggerOps = 0;
self->hasOwner = false; self->hasOwner = false;
#if (CONFIG_MMS_THREADLESS_STACK != 1) #if (CONFIG_MMS_THREADLESS_STACK != 1)
self->createNotificationsMutex = Semaphore_create(1); self->createNotificationsMutex = Semaphore_create(1);
#endif #endif
self->bufferedDataSetValues = NULL; self->bufferedDataSetValues = NULL;
self->valueReferences = NULL; self->valueReferences = NULL;
self->lastEntryId = 0; self->lastEntryId = 0;
self->resvTms = 0; self->resvTms = 0;
self->server = iedServer; self->server = iedServer;
self->reportBuffer = ReportBuffer_create(reportBufferSize); self->reportBuffer = ReportBuffer_create(reportBufferSize);
}
return self; return self;
} }
@ -206,44 +211,46 @@ deleteDataSetValuesShadowBuffer(ReportControl* self)
void void
ReportControl_destroy(ReportControl* self) ReportControl_destroy(ReportControl* self)
{ {
if (self->rcbValues != NULL ) if (self) {
MmsValue_delete(self->rcbValues); if (self->rcbValues != NULL )
MmsValue_delete(self->rcbValues);
if (self->inclusionFlags != NULL) if (self->inclusionFlags != NULL)
GLOBAL_FREEMEM(self->inclusionFlags); GLOBAL_FREEMEM(self->inclusionFlags);
if (self->inclusionField != NULL) if (self->inclusionField != NULL)
MmsValue_delete(self->inclusionField); MmsValue_delete(self->inclusionField);
if (self->buffered == false) if (self->buffered == false)
MmsValue_delete(self->timeOfEntry); MmsValue_delete(self->timeOfEntry);
MmsValue_delete(self->subSeqVal); MmsValue_delete(self->subSeqVal);
deleteDataSetValuesShadowBuffer(self); deleteDataSetValuesShadowBuffer(self);
if (self->isDynamicDataSet) { if (self->isDynamicDataSet) {
if (self->dataSet != NULL) { if (self->dataSet != NULL) {
MmsMapping_freeDynamicallyCreatedDataSet(self->dataSet); MmsMapping_freeDynamicallyCreatedDataSet(self->dataSet);
self->isDynamicDataSet = false; self->isDynamicDataSet = false;
self->dataSet = NULL; self->dataSet = NULL;
}
} }
}
/* restore original sibling of ReportControlBlock */ /* restore original sibling of ReportControlBlock */
self->rcb->sibling = self->sibling; self->rcb->sibling = self->sibling;
self->rcb->trgOps &= ~(64); /* clear runtime mode flag */ self->rcb->trgOps &= ~(64); /* clear runtime mode flag */
ReportBuffer_destroy(self->reportBuffer); ReportBuffer_destroy(self->reportBuffer);
#if (CONFIG_MMS_THREADLESS_STACK != 1) #if (CONFIG_MMS_THREADLESS_STACK != 1)
Semaphore_destroy(self->createNotificationsMutex); Semaphore_destroy(self->createNotificationsMutex);
Semaphore_destroy(self->rcbValuesLock); Semaphore_destroy(self->rcbValuesLock);
#endif #endif
GLOBAL_FREEMEM(self->name); GLOBAL_FREEMEM(self->name);
GLOBAL_FREEMEM(self); GLOBAL_FREEMEM(self);
}
} }
MmsValue* MmsValue*

@ -1,7 +1,7 @@
/* /*
* dynamic_model.c * dynamic_model.c
* *
* Copyright 2014-2016 Michael Zillgith * Copyright 2014-2022 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -761,194 +761,200 @@ DataSetEntry_create(DataSet* dataSet, const char* variable, int index, const cha
static void static void
ModelNode_destroy(ModelNode* modelNode) ModelNode_destroy(ModelNode* modelNode)
{ {
GLOBAL_FREEMEM(modelNode->name); if (modelNode) {
ModelNode* currentChild = modelNode->firstChild; if (modelNode->name)
GLOBAL_FREEMEM(modelNode->name);
while (currentChild != NULL) { ModelNode* currentChild = modelNode->firstChild;
ModelNode* nextChild = currentChild->sibling;
ModelNode_destroy(currentChild); while (currentChild != NULL) {
ModelNode* nextChild = currentChild->sibling;
currentChild = nextChild; ModelNode_destroy(currentChild);
}
currentChild = nextChild;
}
if (modelNode->modelType == DataAttributeModelType) { if (modelNode->modelType == DataAttributeModelType) {
DataAttribute* dataAttribute = (DataAttribute*) modelNode; DataAttribute* dataAttribute = (DataAttribute*) modelNode;
if (dataAttribute->mmsValue != NULL) { if (dataAttribute->mmsValue != NULL) {
MmsValue_delete(dataAttribute->mmsValue); MmsValue_delete(dataAttribute->mmsValue);
dataAttribute->mmsValue = NULL; dataAttribute->mmsValue = NULL;
}
} }
}
GLOBAL_FREEMEM(modelNode); GLOBAL_FREEMEM(modelNode);
}
} }
void void
IedModel_destroy(IedModel* model) IedModel_destroy(IedModel* model)
{ {
/* delete all model nodes and dynamically created strings */ if (model) {
/* delete all model nodes and dynamically created strings */
/* delete all logical devices */ /* delete all logical devices */
LogicalDevice* ld = model->firstChild; LogicalDevice* ld = model->firstChild;
while (ld != NULL) { while (ld != NULL) {
GLOBAL_FREEMEM (ld->name); GLOBAL_FREEMEM (ld->name);
LogicalNode* ln = (LogicalNode*) ld->firstChild; LogicalNode* ln = (LogicalNode*) ld->firstChild;
while (ln != NULL) { while (ln != NULL) {
GLOBAL_FREEMEM(ln->name); GLOBAL_FREEMEM(ln->name);
/* delete all data objects */ /* delete all data objects */
DataObject* currentDataObject = (DataObject*) ln->firstChild; DataObject* currentDataObject = (DataObject*) ln->firstChild;
while (currentDataObject != NULL) { while (currentDataObject != NULL) {
DataObject* nextDataObject = (DataObject*) currentDataObject->sibling; DataObject* nextDataObject = (DataObject*) currentDataObject->sibling;
ModelNode_destroy((ModelNode*) currentDataObject); ModelNode_destroy((ModelNode*) currentDataObject);
currentDataObject = nextDataObject; currentDataObject = nextDataObject;
} }
LogicalNode* currentLn = ln; LogicalNode* currentLn = ln;
ln = (LogicalNode*) ln->sibling; ln = (LogicalNode*) ln->sibling;
GLOBAL_FREEMEM(currentLn); GLOBAL_FREEMEM(currentLn);
} }
LogicalDevice* currentLd = ld; LogicalDevice* currentLd = ld;
ld = (LogicalDevice*) ld->sibling; ld = (LogicalDevice*) ld->sibling;
GLOBAL_FREEMEM(currentLd); GLOBAL_FREEMEM(currentLd);
} }
/* delete all data sets */ /* delete all data sets */
DataSet* dataSet = model->dataSets; DataSet* dataSet = model->dataSets;
while (dataSet != NULL) { while (dataSet != NULL) {
DataSet* nextDataSet = dataSet->sibling; DataSet* nextDataSet = dataSet->sibling;
GLOBAL_FREEMEM(dataSet->name); GLOBAL_FREEMEM(dataSet->name);
DataSetEntry* dse = dataSet->fcdas; DataSetEntry* dse = dataSet->fcdas;
while (dse != NULL) { while (dse != NULL) {
DataSetEntry* nextDse = dse->sibling; DataSetEntry* nextDse = dse->sibling;
if (dse->componentName != NULL) if (dse->componentName != NULL)
GLOBAL_FREEMEM(dse->componentName); GLOBAL_FREEMEM(dse->componentName);
GLOBAL_FREEMEM(dse->variableName); GLOBAL_FREEMEM(dse->variableName);
if (dse->isLDNameDynamicallyAllocated) if (dse->isLDNameDynamicallyAllocated)
GLOBAL_FREEMEM(dse->logicalDeviceName); GLOBAL_FREEMEM(dse->logicalDeviceName);
GLOBAL_FREEMEM(dse); GLOBAL_FREEMEM(dse);
dse = nextDse; dse = nextDse;
} }
GLOBAL_FREEMEM(dataSet); GLOBAL_FREEMEM(dataSet);
dataSet = nextDataSet; dataSet = nextDataSet;
} }
/* delete all RCBs */ /* delete all RCBs */
ReportControlBlock* rcb = model->rcbs; ReportControlBlock* rcb = model->rcbs;
while (rcb != NULL) { while (rcb != NULL) {
ReportControlBlock* nextRcb = rcb->sibling; ReportControlBlock* nextRcb = rcb->sibling;
GLOBAL_FREEMEM(rcb->name); GLOBAL_FREEMEM(rcb->name);
if (rcb->rptId) if (rcb->rptId)
GLOBAL_FREEMEM(rcb->rptId); GLOBAL_FREEMEM(rcb->rptId);
if (rcb->dataSetName) if (rcb->dataSetName)
GLOBAL_FREEMEM(rcb->dataSetName); GLOBAL_FREEMEM(rcb->dataSetName);
GLOBAL_FREEMEM(rcb); GLOBAL_FREEMEM(rcb);
rcb = nextRcb; rcb = nextRcb;
} }
/* delete all GoCBs */ /* delete all GoCBs */
GSEControlBlock* gcb = model->gseCBs; GSEControlBlock* gcb = model->gseCBs;
while (gcb != NULL) { while (gcb != NULL) {
GSEControlBlock* nextGcb = gcb->sibling; GSEControlBlock* nextGcb = gcb->sibling;
GLOBAL_FREEMEM(gcb->name); GLOBAL_FREEMEM(gcb->name);
GLOBAL_FREEMEM(gcb->appId); GLOBAL_FREEMEM(gcb->appId);
GLOBAL_FREEMEM(gcb->dataSetName); GLOBAL_FREEMEM(gcb->dataSetName);
if (gcb->address) if (gcb->address)
GLOBAL_FREEMEM(gcb->address); GLOBAL_FREEMEM(gcb->address);
GLOBAL_FREEMEM(gcb); GLOBAL_FREEMEM(gcb);
gcb = nextGcb; gcb = nextGcb;
} }
/* delete setting controls */ /* delete setting controls */
SettingGroupControlBlock* sgcb = model->sgcbs; SettingGroupControlBlock* sgcb = model->sgcbs;
while (sgcb != NULL) { while (sgcb != NULL) {
SettingGroupControlBlock* nextSgcb = sgcb->sibling; SettingGroupControlBlock* nextSgcb = sgcb->sibling;
GLOBAL_FREEMEM(sgcb); GLOBAL_FREEMEM(sgcb);
sgcb = nextSgcb; sgcb = nextSgcb;
} }
/* delete all LCBs */ /* delete all LCBs */
LogControlBlock* lcb = model->lcbs; LogControlBlock* lcb = model->lcbs;
while (lcb != NULL) { while (lcb != NULL) {
LogControlBlock* nextLcb = lcb->sibling; LogControlBlock* nextLcb = lcb->sibling;
if (lcb->name) if (lcb->name)
GLOBAL_FREEMEM(lcb->name); GLOBAL_FREEMEM(lcb->name);
if (lcb->dataSetName) if (lcb->dataSetName)
GLOBAL_FREEMEM(lcb->dataSetName); GLOBAL_FREEMEM(lcb->dataSetName);
if (lcb->logRef) if (lcb->logRef)
GLOBAL_FREEMEM(lcb->logRef); GLOBAL_FREEMEM(lcb->logRef);
GLOBAL_FREEMEM(lcb); GLOBAL_FREEMEM(lcb);
lcb = nextLcb; lcb = nextLcb;
} }
/* delete all LOGs */ /* delete all LOGs */
Log* log = model->logs; Log* log = model->logs;
while (log != NULL) { while (log != NULL) {
Log* nextLog = log->sibling; Log* nextLog = log->sibling;
if (log->name) if (log->name)
GLOBAL_FREEMEM(log->name); GLOBAL_FREEMEM(log->name);
GLOBAL_FREEMEM(log); GLOBAL_FREEMEM(log);
log = nextLog; log = nextLog;
} }
/* delete generic model parts */ /* delete generic model parts */
if (model->name) if (model->name)
GLOBAL_FREEMEM(model->name); GLOBAL_FREEMEM(model->name);
GLOBAL_FREEMEM(model); GLOBAL_FREEMEM(model);
}
} }

@ -483,23 +483,25 @@ SVPublisher_publish(SVPublisher self)
void void
SVPublisher_destroy(SVPublisher self) SVPublisher_destroy(SVPublisher self)
{ {
if (self->ethernetSocket) if (self) {
Ethernet_destroySocket(self->ethernetSocket); if (self->ethernetSocket)
Ethernet_destroySocket(self->ethernetSocket);
if (self->buffer) if (self->buffer)
GLOBAL_FREEMEM(self->buffer); GLOBAL_FREEMEM(self->buffer);
SVPublisher_ASDU asdu = self->asduList; SVPublisher_ASDU asdu = self->asduList;
while (asdu) { while (asdu) {
SVPublisher_ASDU nextAsdu = asdu->_next; SVPublisher_ASDU nextAsdu = asdu->_next;
GLOBAL_FREEMEM(asdu); GLOBAL_FREEMEM(asdu);
asdu = nextAsdu; asdu = nextAsdu;
} }
GLOBAL_FREEMEM(self); GLOBAL_FREEMEM(self);
}
} }

Loading…
Cancel
Save