From 9e064ab7095293aafc225deee2badda20408ee53 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Mon, 25 Jan 2021 19:06:35 +0100 Subject: [PATCH] - IED Server: prevent integrated GOOSE publisher to crash when ethernet socket cannot be created --- .../server_example_goose.c | 120 +++++++++--------- src/iec61850/server/mms_mapping/mms_goose.c | 43 ++++--- 2 files changed, 85 insertions(+), 78 deletions(-) diff --git a/examples/server_example_goose/server_example_goose.c b/examples/server_example_goose/server_example_goose.c index aa9fc0a0..ef0db87c 100644 --- a/examples/server_example_goose/server_example_goose.c +++ b/examples/server_example_goose/server_example_goose.c @@ -58,99 +58,101 @@ goCbEventHandler(MmsGooseControlBlock goCb, int event, void* parameter) printf(" GoEna: %i\n", MmsGooseControlBlock_getGoEna(goCb)); } -int main(int argc, char** argv) { - +int +main(int argc, char** argv) +{ IedServerConfig config = IedServerConfig_create(); - iedServer = IedServer_createWithConfig(&iedModel, NULL, config); + iedServer = IedServer_createWithConfig(&iedModel, NULL, config); - IedServerConfig_destroy(config); + IedServerConfig_destroy(config); - if (argc > 1) { - char* ethernetIfcID = argv[1]; + if (argc > 1) { + char* ethernetIfcID = argv[1]; - printf("Using GOOSE interface: %s\n", ethernetIfcID); + printf("Using GOOSE interface: %s\n", ethernetIfcID); - /* set GOOSE interface for all GOOSE publishers (GCBs) */ - IedServer_setGooseInterfaceId(iedServer, ethernetIfcID); - } + /* set GOOSE interface for all GOOSE publishers (GCBs) */ + IedServer_setGooseInterfaceId(iedServer, ethernetIfcID); + } - if (argc > 2) { - char* ethernetIfcID = argv[2]; + if (argc > 2) { + char* ethernetIfcID = argv[2]; - printf("Using GOOSE interface for GenericIO/LLN0.gcbAnalogValues: %s\n", ethernetIfcID); + printf("Using GOOSE interface for GenericIO/LLN0.gcbAnalogValues: %s\n", ethernetIfcID); /* set GOOSE interface for a particular GOOSE publisher (GCB) */ - IedServer_setGooseInterfaceIdEx(iedServer, IEDMODEL_GenericIO_LLN0, "gcbAnalogValues", ethernetIfcID); - } + IedServer_setGooseInterfaceIdEx(iedServer, IEDMODEL_GenericIO_LLN0, "gcbAnalogValues", ethernetIfcID); + } - IedServer_setGoCBHandler(iedServer, goCbEventHandler, NULL); + IedServer_setGoCBHandler(iedServer, goCbEventHandler, NULL); - /* MMS server will be instructed to start listening to client connections. */ - IedServer_start(iedServer, 102); + /* MMS server will be instructed to start listening to client connections. */ + IedServer_start(iedServer, 102); - IedServer_setControlHandler(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO1, (ControlHandler) controlHandlerForBinaryOutput, - IEDMODEL_GenericIO_GGIO1_SPCSO1); + IedServer_setControlHandler(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO1, (ControlHandler) controlHandlerForBinaryOutput, + IEDMODEL_GenericIO_GGIO1_SPCSO1); - IedServer_setControlHandler(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO2, (ControlHandler) controlHandlerForBinaryOutput, - IEDMODEL_GenericIO_GGIO1_SPCSO2); + IedServer_setControlHandler(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO2, (ControlHandler) controlHandlerForBinaryOutput, + IEDMODEL_GenericIO_GGIO1_SPCSO2); - IedServer_setControlHandler(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO3, (ControlHandler) controlHandlerForBinaryOutput, - IEDMODEL_GenericIO_GGIO1_SPCSO3); + IedServer_setControlHandler(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO3, (ControlHandler) controlHandlerForBinaryOutput, + IEDMODEL_GenericIO_GGIO1_SPCSO3); - IedServer_setControlHandler(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO4, (ControlHandler) controlHandlerForBinaryOutput, - IEDMODEL_GenericIO_GGIO1_SPCSO4); + IedServer_setControlHandler(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO4, (ControlHandler) controlHandlerForBinaryOutput, + IEDMODEL_GenericIO_GGIO1_SPCSO4); - if (!IedServer_isRunning(iedServer)) { - printf("Starting server failed! Exit.\n"); - IedServer_destroy(iedServer); - exit(-1); - } + if (!IedServer_isRunning(iedServer)) { + printf("Starting server failed! Exit.\n"); + IedServer_destroy(iedServer); + exit(-1); + } - /* Start GOOSE publishing */ - IedServer_enableGoosePublishing(iedServer); + /* Start GOOSE publishing */ + IedServer_enableGoosePublishing(iedServer); - running = 1; + running = 1; - signal(SIGINT, sigint_handler); + signal(SIGINT, sigint_handler); - float anIn1 = 0.f; + float anIn1 = 0.f; - int eventCount = 10; + int eventCount = 10; - while (running) { + while (running) { - IedServer_lockDataModel(iedServer); + IedServer_lockDataModel(iedServer); IedServer_updateUTCTimeAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_AnIn1_t, Hal_getTimeInMs()); - IedServer_updateFloatAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_AnIn1_mag_f, anIn1); + IedServer_updateFloatAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_AnIn1_mag_f, anIn1); - if (eventCount) { - IedServer_updateUTCTimeAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO4_t, Hal_getTimeInMs()); + if (eventCount) { + IedServer_updateUTCTimeAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO4_t, Hal_getTimeInMs()); - if (eventCount % 2) { - IedServer_updateQuality(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO4_q, QUALITY_VALIDITY_GOOD); - IedServer_updateBooleanAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO4_stVal, true); - } - else { + if (eventCount % 2) { + IedServer_updateQuality(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO4_q, QUALITY_VALIDITY_GOOD); + IedServer_updateBooleanAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO4_stVal, true); + } + else { IedServer_updateQuality(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO4_q, QUALITY_VALIDITY_INVALID); IedServer_updateBooleanAttributeValue(iedServer, IEDMODEL_GenericIO_GGIO1_SPCSO4_stVal, false); - } + } + + eventCount--; + } - eventCount--; - } + IedServer_unlockDataModel(iedServer); - IedServer_unlockDataModel(iedServer); + anIn1 += 0.1; - anIn1 += 0.1; + Thread_sleep(1000); + } - Thread_sleep(1000); - } + /* stop MMS server - close TCP server socket and all client sockets */ + IedServer_stop(iedServer); - /* stop MMS server - close TCP server socket and all client sockets */ - IedServer_stop(iedServer); + /* Cleanup - free all resources */ + IedServer_destroy(iedServer); - /* Cleanup - free all resources */ - IedServer_destroy(iedServer); - return 0; + return 0; } /* main() */ diff --git a/src/iec61850/server/mms_mapping/mms_goose.c b/src/iec61850/server/mms_mapping/mms_goose.c index 80ca121b..730bbfff 100644 --- a/src/iec61850/server/mms_mapping/mms_goose.c +++ b/src/iec61850/server/mms_mapping/mms_goose.c @@ -508,37 +508,39 @@ MmsGooseControlBlock_disable(MmsGooseControlBlock self, MmsMapping* mmsMapping) void MmsGooseControlBlock_checkAndPublish(MmsGooseControlBlock self, uint64_t currentTime) { - if (currentTime >= self->nextPublishTime) { + if (self->publisher) { + 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 - } - else if ((self->nextPublishTime - currentTime) > ((uint32_t) self->maxTime * 2)) { - self->nextPublishTime = currentTime + self->minTime; + } + else if ((self->nextPublishTime - currentTime) > ((uint32_t) self->maxTime * 2)) { + self->nextPublishTime = currentTime + self->minTime; + } } } @@ -551,6 +553,9 @@ MmsGooseControlBlock_setStateChangePending(MmsGooseControlBlock self) void MmsGooseControlBlock_publishNewState(MmsGooseControlBlock self) { + if (self->publisher == false) + return; + if (self->stateChangePending) { #if (CONFIG_MMS_THREADLESS_STACK != 1) Semaphore_wait(self->publisherMutex);