From 3ac4cd88dfe670ead6a0faf9a1163b1e58fdcba8 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Mon, 12 Jun 2017 22:22:45 +0200 Subject: [PATCH] - fixed memory cleanup in GOOSE subscriber - added GooseReceiver_isRunning function - updated goose_subscriber example --- examples/CMakeLists.txt | 3 ++ .../goose_subscriber_example.c | 21 +++------ .../iec61850_client_example_files/file-tool.c | 2 + src/goose/goose_receiver.c | 44 +++++++++++++++---- src/goose/goose_receiver.h | 10 ++++- src/iec61850/inc/iec61850_client.h | 5 ++- src/iec61850/inc/iec61850_model.h | 3 +- src/iec61850/server/mms_mapping/mms_mapping.c | 2 +- src/vs/libiec61850-wo-goose.def | 2 +- src/vs/libiec61850.def | 1 + 10 files changed, 65 insertions(+), 28 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index a09192d..cfb8f63 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -17,7 +17,10 @@ add_subdirectory(iec61850_client_example2) add_subdirectory(iec61850_client_example3) add_subdirectory(iec61850_client_example4) add_subdirectory(iec61850_client_example5) +IF(WIN32) +else() add_subdirectory(iec61850_client_example_files) +endif() add_subdirectory(iec61850_client_example_reporting) add_subdirectory(iec61850_client_example_log) add_subdirectory(mms_client_example1) diff --git a/examples/goose_subscriber/goose_subscriber_example.c b/examples/goose_subscriber/goose_subscriber_example.c index c9a7e10..5d28534 100644 --- a/examples/goose_subscriber/goose_subscriber_example.c +++ b/examples/goose_subscriber/goose_subscriber_example.c @@ -12,8 +12,6 @@ #include #include #include -#define __STDC_FORMAT_MACROS /* otherwise PRIu64 is not defined for MinGW */ -#include static int running = 1; @@ -29,9 +27,10 @@ gooseListener(GooseSubscriber subscriber, void* parameter) printf(" stNum: %u sqNum: %u\n", GooseSubscriber_getStNum(subscriber), GooseSubscriber_getSqNum(subscriber)); printf(" timeToLive: %u\n", GooseSubscriber_getTimeAllowedToLive(subscriber)); -#ifndef _WIN32 - printf(" timestamp: %"PRIu64"\n", GooseSubscriber_getTimestamp(subscriber)); -#endif + + uint64_t timestamp = GooseSubscriber_getTimestamp(subscriber); + + printf(" timestamp: %u.%u\n", (uint32_t) (timestamp / 1000), (uint32_t) (timestamp % 1000)); MmsValue* values = GooseSubscriber_getDataSetValues(subscriber); @@ -45,14 +44,6 @@ gooseListener(GooseSubscriber subscriber, void* parameter) int main(int argc, char** argv) { - MmsValue* dataSetValues = MmsValue_createEmptyArray(4); - - int i; - for (i = 0; i < 4; i++) { - MmsValue* dataSetEntry = MmsValue_newBoolean(false); - MmsValue_setElement(dataSetValues, i, dataSetEntry); - } - GooseReceiver receiver = GooseReceiver_create(); if (argc > 1) { @@ -80,5 +71,7 @@ main(int argc, char** argv) Thread_sleep(100); } - GooseSubscriber_destroy(subscriber); + GooseReceiver_stop(receiver); + + GooseReceiver_destroy(receiver); } diff --git a/examples/iec61850_client_example_files/file-tool.c b/examples/iec61850_client_example_files/file-tool.c index 492dd0c..4610c7b 100644 --- a/examples/iec61850_client_example_files/file-tool.c +++ b/examples/iec61850_client_example_files/file-tool.c @@ -8,6 +8,8 @@ * * Note: intended to be used with server_example3 or server_example_files * + * Note: DOES NOT WORK WITH VISUAL STUDIO because of libgen.h + * */ #include "iec61850_client.h" diff --git a/src/goose/goose_receiver.c b/src/goose/goose_receiver.c index 26618ee..0f1b535 100644 --- a/src/goose/goose_receiver.c +++ b/src/goose/goose_receiver.c @@ -1,7 +1,7 @@ /* * goose_receiver.c * - * Copyright 2014, 2015 Michael Zillgith + * Copyright 2014-2017 Michael Zillgith * * This file is part of libIEC61850. * @@ -52,6 +52,9 @@ struct sGooseReceiver { uint8_t* buffer; EthernetSocket ethSocket; LinkedList subscriberList; +#if (CONFIG_MMS_THREADLESS_STACK == 0) + Thread thread; +#endif }; @@ -66,6 +69,9 @@ GooseReceiver_create() self->buffer = (uint8_t*) GLOBAL_MALLOC(ETH_BUFFER_LENGTH); self->ethSocket = NULL; self->subscriberList = LinkedList_create(); +#if (CONFIG_MMS_THREADLESS_STACK == 0) + self->thread = NULL; +#endif } return self; @@ -712,33 +718,52 @@ gooseReceiverLoop(void* threadParameter) void GooseReceiver_start(GooseReceiver self) { - Thread thread = Thread_create((ThreadExecutionFunction) gooseReceiverLoop, (void*) self, true); +#if (CONFIG_MMS_THREADLESS_STACK == 0) + self->thread = Thread_create((ThreadExecutionFunction) gooseReceiverLoop, (void*) self, false); - if (thread != NULL) { + if (self->thread != NULL) { if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER: GOOSE receiver started for interface %s\n", self->interfaceId); - Thread_start(thread); + Thread_start(self->thread); } else { if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER: Starting GOOSE receiver failed for interface %s\n", self->interfaceId); } +#endif +} +bool +GooseReceiver_isRunning(GooseReceiver self) +{ + return self->running; } void GooseReceiver_stop(GooseReceiver self) { +#if (CONFIG_MMS_THREADLESS_STACK == 0) self->running = false; + Thread_destroy(self->thread); + while (self->stopped == false) Thread_sleep(1); +#endif } void GooseReceiver_destroy(GooseReceiver self) { +#if (CONFIG_MMS_THREADLESS_STACK == 0) + if ((self->thread != NULL) && (GooseReceiver_isRunning(self))) + GooseReceiver_stop(self); +#endif + + if (self->interfaceId != NULL) + GLOBAL_FREEMEM(self->interfaceId); + LinkedList_destroyDeep(self->subscriberList, (LinkedListValueDeleteFunction) GooseSubscriber_destroy); @@ -757,9 +782,12 @@ GooseReceiver_startThreadless(GooseReceiver self) else self->ethSocket = Ethernet_createSocket(self->interfaceId, NULL); - Ethernet_setProtocolFilter(self->ethSocket, ETH_P_GOOSE); - - self->running = true; + if (self->ethSocket != NULL) { + Ethernet_setProtocolFilter(self->ethSocket, ETH_P_GOOSE); + self->running = true; + } + else + self->running = false; } void @@ -770,7 +798,7 @@ GooseReceiver_stopThreadless(GooseReceiver self) self->running = false; } -// call after reception of ethernet frame and periodically to to house keeping tasks +// call after reception of ethernet frame bool GooseReceiver_tick(GooseReceiver self) { diff --git a/src/goose/goose_receiver.h b/src/goose/goose_receiver.h index 51bdebc..8ba5648 100644 --- a/src/goose/goose_receiver.h +++ b/src/goose/goose_receiver.h @@ -92,7 +92,7 @@ void GooseReceiver_start(GooseReceiver self); /** - * \brief stop the GOOSE receiver running in a speparate thread + * \brief stop the GOOSE receiver running in a separate thread * * This function is used to stop the receiver thread started with GooseReceiver_start * @@ -101,6 +101,14 @@ GooseReceiver_start(GooseReceiver self); void GooseReceiver_stop(GooseReceiver self); +bool +GooseReceiver_isRunning(GooseReceiver self); + +/** + * \brief Free all resource of the GooseReceiver and all installed GooseSubscribers + * + * \param self the GooseReceiver instance + */ void GooseReceiver_destroy(GooseReceiver self); diff --git a/src/iec61850/inc/iec61850_client.h b/src/iec61850/inc/iec61850_client.h index 3319eba..deec194 100644 --- a/src/iec61850/inc/iec61850_client.h +++ b/src/iec61850/inc/iec61850_client.h @@ -625,7 +625,7 @@ IedConnection_setGoCBValues(IedConnection self, IedClientError* error, ClientGoo * * The requested RCB has to be specified by its object reference. E.g. * - * "simpleIOGernericIO/LLN0.RP.EventsRCB01" + * "simpleIOGenericIO/LLN0.RP.EventsRCB01" * * or * @@ -1218,7 +1218,8 @@ IedConnection_readUnsigned32Value(IedConnection self, IedClientError* error, con * \brief read a functional constrained data attribute (FCDA) of type Timestamp (UTC Time) * * NOTE: If the timestamp parameter is set to NULL the function allocates a new timestamp instance. Otherwise the - * return value is a pointer to the user provided timestamp instance. + * return value is a pointer to the user provided timestamp instance. The new timestamp instance has to be freed by + * the caller of the function. * * \param self the connection object to operate on * \param error the error code if an error occurs diff --git a/src/iec61850/inc/iec61850_model.h b/src/iec61850/inc/iec61850_model.h index 9dad53c..0b37007 100644 --- a/src/iec61850/inc/iec61850_model.h +++ b/src/iec61850/inc/iec61850_model.h @@ -151,7 +151,8 @@ typedef enum { GENERIC_BITSTRING = 26, CONSTRUCTED = 27, ENTRY_TIME = 28, - PHYCOMADDR = 29 + PHYCOMADDR = 29, + CURRENCY = 30 #endif } DataAttributeType; diff --git a/src/iec61850/server/mms_mapping/mms_mapping.c b/src/iec61850/server/mms_mapping/mms_mapping.c index 7e9e5d9..cdd0be6 100644 --- a/src/iec61850/server/mms_mapping/mms_mapping.c +++ b/src/iec61850/server/mms_mapping/mms_mapping.c @@ -2032,7 +2032,7 @@ mmsWriteHandler(void* parameter, MmsDomain* domain, } #endif - /* Call writer access handlers */ + /* Call write access handlers */ LinkedList writeHandlerListElement = LinkedList_getNext(self->attributeAccessHandlers); while (writeHandlerListElement != NULL) { diff --git a/src/vs/libiec61850-wo-goose.def b/src/vs/libiec61850-wo-goose.def index 0efd583..757cbcc 100644 --- a/src/vs/libiec61850-wo-goose.def +++ b/src/vs/libiec61850-wo-goose.def @@ -568,4 +568,4 @@ EXPORTS MmsConnection_setFilestoreBasepath IedConnection_setFilestoreBasepath IedServer_setFilestoreBasepath - \ No newline at end of file + GooseReceiver_isRunning diff --git a/src/vs/libiec61850.def b/src/vs/libiec61850.def index 4853466..ef9e200 100644 --- a/src/vs/libiec61850.def +++ b/src/vs/libiec61850.def @@ -646,3 +646,4 @@ EXPORTS MmsConnection_setFilestoreBasepath IedConnection_setFilestoreBasepath IedServer_setFilestoreBasepath + GooseReceiver_isRunning