- fixed memory cleanup in GOOSE subscriber
- added GooseReceiver_isRunning function - updated goose_subscriber example
This commit is contained in:
parent
dcbc3de0de
commit
3ac4cd88df
10 changed files with 65 additions and 28 deletions
|
@ -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)
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#define __STDC_FORMAT_MACROS /* otherwise PRIu64 is not defined for MinGW */
|
||||
#include <inttypes.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -151,7 +151,8 @@ typedef enum {
|
|||
GENERIC_BITSTRING = 26,
|
||||
CONSTRUCTED = 27,
|
||||
ENTRY_TIME = 28,
|
||||
PHYCOMADDR = 29
|
||||
PHYCOMADDR = 29,
|
||||
CURRENCY = 30
|
||||
#endif
|
||||
} DataAttributeType;
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -568,4 +568,4 @@ EXPORTS
|
|||
MmsConnection_setFilestoreBasepath
|
||||
IedConnection_setFilestoreBasepath
|
||||
IedServer_setFilestoreBasepath
|
||||
|
||||
GooseReceiver_isRunning
|
||||
|
|
|
@ -646,3 +646,4 @@ EXPORTS
|
|||
MmsConnection_setFilestoreBasepath
|
||||
IedConnection_setFilestoreBasepath
|
||||
IedServer_setFilestoreBasepath
|
||||
GooseReceiver_isRunning
|
||||
|
|
Loading…
Add table
Reference in a new issue