- .NET API: GooseSubscriber - added GetGoId, GetGoCbRef, GetFataSet

methods
- .NET API: GooseReceiver - store references to all added
GooseSubscribers to prevent garbage collection
- update documentation comments for GooseSubscriber API
pull/341/head
Michael Zillgith 4 years ago
parent 2ace50b712
commit bb64d9d8fe

@ -22,6 +22,7 @@
*/
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using IEC61850.Common;
@ -69,6 +70,8 @@ namespace IEC61850
private bool isDisposed = false;
private List<GooseSubscriber> subscribers = new List<GooseSubscriber>();
public GooseReceiver()
{
self = GooseReceiver_create ();
@ -79,14 +82,29 @@ namespace IEC61850
GooseReceiver_setInterfaceId (self, interfaceId);
}
/// <summary>
/// Add the subscriber to be handled by this receiver instance
/// </summary>
/// <remarks>A GooseSubscriber can only be added to one GooseReceiver!</remarks>
/// <param name="subscriber"></param>
public void AddSubscriber(GooseSubscriber subscriber)
{
if (subscriber.attachedToReceiver == false)
{
subscriber.attachedToReceiver = true;
GooseReceiver_addSubscriber(self, subscriber.self);
subscribers.Add(subscriber);
}
}
public void RemoveSubscriber(GooseSubscriber subscriber)
{
if (subscriber.attachedToReceiver)
{
GooseReceiver_removeSubscriber(self, subscriber.self);
subscribers.Remove(subscriber);
subscriber.attachedToReceiver = false;
}
}
public void Start()
@ -175,10 +193,22 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void GooseSubscriber_setListener (IntPtr self, InternalGooseListener listener, IntPtr parameter);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GooseSubscriber_getGoId(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GooseSubscriber_getGoCbRef(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GooseSubscriber_getDataSet(IntPtr self);
internal IntPtr self;
private bool isDisposed = false;
// don't call native destructor when attached to a receiver
internal bool attachedToReceiver = false;
private GooseListener listener = null;
private object listenerParameter = null;
@ -214,7 +244,6 @@ namespace IEC61850
return GooseSubscriber_isValid (self);
}
public void SetListener(GooseListener listener, object parameter)
{
this.listener = listener;
@ -227,6 +256,21 @@ namespace IEC61850
}
}
public string GetGoId()
{
return Marshal.PtrToStringAnsi(GooseSubscriber_getGoId(self));
}
public string GetGoCbRef()
{
return Marshal.PtrToStringAnsi(GooseSubscriber_getGoCbRef(self));
}
public string GetDataSet()
{
return Marshal.PtrToStringAnsi(GooseSubscriber_getDataSet(self));
}
public UInt32 GetStNum()
{
return GooseSubscriber_getStNum (self);
@ -300,11 +344,19 @@ namespace IEC61850
{
if (isDisposed == false) {
isDisposed = true;
if (attachedToReceiver == false)
GooseSubscriber_destroy (self);
self = IntPtr.Zero;
}
}
~GooseSubscriber()
{
Dispose();
}
}
}

@ -886,7 +886,7 @@ namespace IEC61850
/// Creates a new SampledValuesControlBlock instance.
/// </summary>
/// <returns>The new GoCB instance</returns>
/// <param name="gocbObjectReference">The object reference of the GoCB</param>
/// <param name="gocbObjectReference">The object reference of the GoCB (e.g. "simpleIOGenericIO/LLN0.gcbAnalogValues")</param>
public GooseControlBlock GetGooseControlBlock(string gocbObjectReference)
{
return new GooseControlBlock(gocbObjectReference, connection);

@ -4,6 +4,9 @@ using IEC61850.GOOSE.Subscriber;
using System.Threading;
using IEC61850.Common;
/// <summary>
/// This example is intended to be
/// </summary>
namespace goose_subscriber
{
class MainClass
@ -11,9 +14,10 @@ namespace goose_subscriber
private static void gooseListener (GooseSubscriber subscriber, object parameter)
{
Console.WriteLine ("Received GOOSE message:\n-------------------------");
Console.WriteLine (" GoID: " + subscriber.GetGoId());
Console.WriteLine (" GoCbRef: " + subscriber.GetGoCbRef());
Console.WriteLine (" DatSet: " + subscriber.GetDataSet());
Console.WriteLine (" stNum: " + subscriber.GetStNum ());
Console.WriteLine (" sqNum: " + subscriber.GetSqNum ());
@ -33,17 +37,27 @@ namespace goose_subscriber
GooseReceiver receiver = new GooseReceiver ();
receiver.SetInterfaceId ("eth0");
//receiver.SetInterfaceId("0"); // on windows use the interface index starting with 0
GooseSubscriber subscriber = new GooseSubscriber ("simpleIOGenericIO/LLN0$GO$gcbAnalogValues");
subscriber.SetAppId(1000);
// APP-ID has to match the APP-ID of the publisher
subscriber.SetAppId(4096);
subscriber.SetListener (gooseListener, null);
receiver.AddSubscriber (subscriber);
GooseSubscriber subscriber2 = new GooseSubscriber("simpleIOGenericIO/LLN0$GO$gcbEvents");
subscriber2.SetAppId(4096);
subscriber2.SetListener(gooseListener, null);
receiver.AddSubscriber(subscriber2);
receiver.Start ();
subscriber = null;
if (receiver.IsRunning ()) {
bool running = true;

@ -1,7 +1,7 @@
/*
* goose_subscriber.h
*
* Copyright 2013-2018 Michael Zillgith
* Copyright 2013-2021 Michael Zillgith
*
* This file is part of libIEC61850.
*
@ -82,12 +82,27 @@ typedef void (*GooseListener)(GooseSubscriber subscriber, void* parameter);
LIB61850_API GooseSubscriber
GooseSubscriber_create(char* goCbRef, MmsValue* dataSetValues);
/**
* \brief Get the GoId value of the received GOOSE message
*
* \param self GooseSubscriber instance to operate on.
*/
LIB61850_API char*
GooseSubscriber_getGoId(GooseSubscriber self);
/**
* \brief Get the GOOSE Control Block reference value of the received GOOSE message
*
* \param self GooseSubscriber instance to operate on.
*/
LIB61850_API char*
GooseSubscriber_getGoCbRef(GooseSubscriber self);
/**
* \brief Get the DatSet value of the received GOOSE message
*
* \param self GooseSubscriber instance to operate on.
*/
LIB61850_API char*
GooseSubscriber_getDataSet(GooseSubscriber self);
@ -133,6 +148,14 @@ GooseSubscriber_isValid(GooseSubscriber self);
LIB61850_API GooseParseError
GooseSubscriber_getParseError(GooseSubscriber self);
/**
* \brief Destroy the GooseSubscriber instance
*
* Do not call this function when the GooseSubscriber instance was added to a GooseReceiver.
* The GooseReceiver will call the destructor when \ref GooseReceiver_destroy is called!
*
* \param self GooseSubscriber instance to operate on.
*/
LIB61850_API void
GooseSubscriber_destroy(GooseSubscriber self);
@ -146,14 +169,32 @@ GooseSubscriber_destroy(GooseSubscriber self);
LIB61850_API void
GooseSubscriber_setListener(GooseSubscriber self, GooseListener listener, void* parameter);
/**
* \brief Get the APPID value of the received GOOSE message
*
* \param self GooseSubscriber instance to operate on.
*/
LIB61850_API int32_t
GooseSubscriber_getAppId(GooseSubscriber self);
/**
* \brief Get the source MAC address of the received GOOSE message
*
* \param self GooseSubscriber instance to operate on.
* \param buffer buffer to store the MAC address (at least 6 byte)
*/
LIB61850_API void
GooseSubscriber_getSrcMac(GooseSubscriber self, uint8_t* buffer);
/**
* \brief Get the destination MAC address of the received GOOSE message
*
* \param self GooseSubscriber instance to operate on.
* \param buffer buffer to store the MAC address (at least 6 byte)
*/
LIB61850_API void
GooseSubscriber_getDstMac(GooseSubscriber self, uint8_t* buffer);
/**
* \brief return the state number (stNum) of the last received GOOSE message.
*

Loading…
Cancel
Save