/*
* ReportControlBlock.cs
*
* Copyright 2014 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see .
*
* See COPYING file for the complete license text.
*/
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using IEC61850.Common;
namespace IEC61850
{
namespace Client
{
///
/// Report handler.
///
public delegate void ReportHandler (Report report, object parameter);
///
/// Report control block (RCB) representation.
///
///
/// This class is used as a client side representation (copy) of a report control block (RCB).
/// Values from the server will only be read when the GetRCBValues method is called.
/// Values at the server are only affected when the SetRCBValues method is called.
///
public class ReportControlBlock
{
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientReportControlBlock_create (string dataAttributeReference);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr IedConnection_getRCBValues (IntPtr connection, out int error, string rcbReference, IntPtr updateRcb);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedConnection_setRCBValues (IntPtr connection, out int error, IntPtr rcb, UInt32 parametersMask, bool singleRequest);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReportControlBlock_isBuffered (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientReportControlBlock_getRptId (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setRptId (IntPtr self, string rptId);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReportControlBlock_getRptEna (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setRptEna(IntPtr self, bool rptEna);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReportControlBlock_getResv (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setResv (IntPtr self, bool resv);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientReportControlBlock_getDataSetReference (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setDataSetReference (IntPtr self, string dataSetReference);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 ClientReportControlBlock_getConfRev (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int ClientReportControlBlock_getOptFlds (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setOptFlds (IntPtr self, int optFlds);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 ClientReportControlBlock_getBufTm (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setBufTm (IntPtr self, UInt32 bufTm);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt16 ClientReportControlBlock_getSqNum (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int ClientReportControlBlock_getTrgOps (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setTrgOps (IntPtr self, int trgOps);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 ClientReportControlBlock_getIntgPd (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setIntgPd (IntPtr self, UInt32 intgPd);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReportControlBlock_getGI (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setGI (IntPtr self, bool gi);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReportControlBlock_getPurgeBuf (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setPurgeBuf (IntPtr self, bool purgeBuf);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern Int32 ClientReportControlBlock_getResvTms (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setResvTms (IntPtr self, Int16 resvTms);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientReportControlBlock_getEntryId (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setEntryId (IntPtr self, IntPtr entryId);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt64 ClientReportControlBlock_getEntryTime (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientReportControlBlock_getOwner (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedConnection_installReportHandler (IntPtr connection, string rcbReference, string rptId, InternalReportHandler handler,
IntPtr handlerParameter);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedConnection_uninstallReportHandler(IntPtr connection, string rcbReference);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void InternalReportHandler (IntPtr parameter, IntPtr report);
private IntPtr self;
private IntPtr connection;
private IedConnection iedConnection = null;
private string objectReference;
private bool flagRptId = false;
private bool flagRptEna = false;
private bool flagResv = false;
private bool flagDataSetReference = false;
private bool flagConfRev = false;
private bool flagOptFlds = false;
private bool flagBufTm = false;
private bool flagSqNum = false;
private bool flagTrgOps = false;
private bool flagIntgPd = false;
private bool flagGI = false;
private bool flagPurgeBuf = false;
private bool flagResvTms = false;
private bool flagEntryId = false;
private event ReportHandler reportHandler = null;
private object reportHandlerParameter;
private bool reportHandlerInstalled = false;
private event InternalReportHandler internalHandler = null;
private void resetSendFlags ()
{
flagRptId = false;
flagRptEna = false;
flagResv = false;
flagDataSetReference = false;
flagConfRev = false;
flagOptFlds = false;
flagBufTm = false;
flagSqNum = false;
flagTrgOps = false;
flagIntgPd = false;
flagGI = false;
flagPurgeBuf = false;
flagResvTms = false;
flagEntryId = false;
}
private Report report = null;
private void internalReportHandler (IntPtr parameter, IntPtr report)
{
try {
if (this.report == null)
this.report = new Report (report);
if (reportHandler != null)
reportHandler(this.report, reportHandlerParameter);
} catch (Exception e)
{
// older versions of mono 2.10 (for linux?) cause this exception
Console.WriteLine(e.Message);
}
}
internal ReportControlBlock (string objectReference, IedConnection iedConnection, IntPtr connection)
{
self = ClientReportControlBlock_create (objectReference);
this.iedConnection = iedConnection;
this.connection = connection;
this.objectReference = objectReference;
}
internal void DisposeInternal()
{
IedConnection_uninstallReportHandler(connection, objectReference);
}
///
/// Releases all resource used by the object.
///
/// Call when you are finished using the . The
/// method leaves the in an unusable state.
/// After calling , you must release all references to the
/// so the garbage collector can reclaim the memory that the
/// was occupying.
public void Dispose()
{
DisposeInternal ();
iedConnection.RemoveRCB (this);
}
public string GetObjectReference ()
{
return this.objectReference;
}
///
/// Installs the report handler.
///
///
/// This will install a callback handler (delegate) that is invoked whenever a report
/// related to this RCB is received. Any call of this method will replace an previously registered
/// handler!
///
///
/// report handler
///
///
/// parameter is passed to the handler when the handler is invoked.
///
public void InstallReportHandler (ReportHandler reportHandler, object parameter)
{
this.reportHandler = new ReportHandler(reportHandler);
this.reportHandlerParameter = parameter;
if (reportHandlerInstalled == false) {
string reportId = this.GetRptId ();
if (internalHandler == null)
{
internalHandler = new InternalReportHandler(internalReportHandler);
}
IedConnection_installReportHandler(this.connection, objectReference, reportId, internalHandler, IntPtr.Zero);
reportHandlerInstalled = true;
}
}
///
/// Read all RCB values from the server
///
/// This exception is thrown if there is a connection or service error
public void GetRCBValues ()
{
int error;
IedConnection_getRCBValues (connection, out error, objectReference, self);
if (error != 0)
throw new IedConnectionException ("getRCBValues service failed", error);
}
///
/// Write changed RCB values to the server.
///
///
/// This function will only write the RCB values that were set by one of the setter methods.
/// The RCB values are sent by a single MMS write request.
///
/// This exception is thrown if there is a connection or service error
public void SetRCBValues ()
{
SetRCBValues (true);
}
///
/// Write changed RCB values to the server.
///
///
/// This function will only write the RCB values that were set by one of the setter methods.
///
/// This exception is thrown if there is a connection or service error
///
/// If true the values are sent by single MMS write request. Otherwise the values are all sent by their own MMS write requests.
///
public void SetRCBValues (bool singleRequest)
{
UInt32 parametersMask = 0;
if (flagRptId)
parametersMask += 1;
if (flagRptEna)
parametersMask += 2;
if (flagResv)
parametersMask += 4;
if (flagDataSetReference)
parametersMask += 8;
if (flagConfRev)
parametersMask += 16;
if (flagOptFlds)
parametersMask += 32;
if (flagBufTm)
parametersMask += 64;
if (flagSqNum)
parametersMask += 128;
if (flagTrgOps)
parametersMask += 256;
if (flagIntgPd)
parametersMask += 512;
if (flagGI)
parametersMask += 1024;
if (flagPurgeBuf)
parametersMask += 2048;
if (flagEntryId)
parametersMask += 4096;
if (flagResvTms)
parametersMask += 16384;
int error;
IedConnection_setRCBValues (connection, out error, self, parametersMask, singleRequest);
resetSendFlags();
if (error != 0)
throw new IedConnectionException ("setRCBValues service failed", error);
if (flagRptId) {
if (reportHandlerInstalled) {
reportHandlerInstalled = false;
InstallReportHandler(this.reportHandler, this.reportHandlerParameter);
}
}
}
///
/// Determines whether this instance is a buffered or unbuffered RCB.
///
///
/// true if this instance is a buffered RCB; otherwise, false.
///
public bool IsBuffered ()
{
return ClientReportControlBlock_isBuffered (self);
}
///
/// Gets the entry time of the RCB as ms time
///
///
/// The entry time is the timestamp of the last report sent.
///
///
/// The entry time as ms timestamp
///
public UInt64 GetEntryTime ()
{
return ClientReportControlBlock_getEntryTime (self);
}
///
/// Gets the entry time of the RCB as DateTimeOffset
///
///
/// The entry time is the timestamp of the last report sent.
///
///
/// The entry time as DataTimeOffset
///
public DateTimeOffset GetEntryTimeAsDateTimeOffset ()
{
UInt64 entryTime = GetEntryTime ();
DateTimeOffset retVal = new DateTimeOffset (1970, 1, 1, 0, 0, 0, TimeSpan.Zero);
return retVal.AddMilliseconds (entryTime);
}
///
/// Gets the entryID of RCB
///
/// Returns the EntryID of the last received GetRCBValues service response.
/// The EntryID is only present in buffered RCBs (BRCBs).
///
/// The entry ID
public byte[] GetEntryID()
{
IntPtr entryIdRef = ClientReportControlBlock_getEntryId (self);
if (entryIdRef == IntPtr.Zero)
return null;
else {
MmsValue entryId = new MmsValue (entryIdRef);
return entryId.getOctetString ();
}
}
public void SetEntryID(byte[] entryId)
{
flagEntryId = true;
MmsValue entryID = MmsValue.NewOctetString (entryId.Length);
entryID.setOctetString (entryId);
ClientReportControlBlock_setEntryId (self, entryID.valueReference);
}
///
/// Gets the data set reference of the associated data set
///
///
/// The data set reference.
///
public string GetDataSetReference ()
{
IntPtr dataSetRefPtr = ClientReportControlBlock_getDataSetReference (self);
return Marshal.PtrToStringAnsi (dataSetRefPtr);
}
///
/// Sets the data set reference. Use this method to select the associated data set for the RCB
///
///
/// The data set reference.
///
public void SetDataSetReference (string dataSetReference)
{
ClientReportControlBlock_setDataSetReference (self, dataSetReference);
flagDataSetReference = true;
}
///
/// Gets the report identifier.
///
///
/// The report identifier.
///
public string GetRptId ()
{
IntPtr rptIdPtr = ClientReportControlBlock_getRptId (self);
return Marshal.PtrToStringAnsi (rptIdPtr);
}
///
/// Sets the RptId (report ID) of the RCB
///
///
/// The new RptId
///
public void SetRptId (string rptId)
{
ClientReportControlBlock_setRptId(self, rptId);
flagRptId = true;
}
///
/// Check if reporting is currently enabled
///
///
/// true, if reporting is enabled, false otherwise
///
public bool GetRptEna ()
{
return ClientReportControlBlock_getRptEna (self);
}
///
/// Sets report enable flag. Use this to enable reporting
///
///
/// true to enable reporting, false to disable
///
public void SetRptEna (bool rptEna)
{
ClientReportControlBlock_setRptEna (self, rptEna);
flagRptEna = true;
}
///
/// Get the purgeBuf flag of the report control block
///
/// the prugeBuf value
public bool GetPurgeBuf ()
{
return ClientReportControlBlock_getPurgeBuf(self);
}
///
/// Set the purgeBuf flag of the report control block
///
/// This is only for buffered RCBs. If set to true the report buffer of a buffered RCB will be cleaned.
/// set to true to flush report buffer
public void SetPurgeBuf (bool purgeBuf)
{
ClientReportControlBlock_setPurgeBuf(self, purgeBuf);
flagPurgeBuf = true;
}
///
/// Gets the buffer time.
///
///
/// The buffer time in ms.
///
public UInt32 GetBufTm()
{
return ClientReportControlBlock_getBufTm (self);
}
///
/// Sets the buffer time.
///
///
/// Buffer time is ms.
///
public void SetBufTm (UInt32 bufTm)
{
ClientReportControlBlock_setBufTm (self, bufTm);
flagBufTm = true;
}
///
/// Gets the GI flag
///
///
/// true, if GI flag is set
///
public bool GetGI ()
{
return ClientReportControlBlock_getGI (self);
}
///
/// Sets the GI flag. Use this to trigger a GI (general interrogation) command.
///
///
/// request general interrogation of true
///
public void SetGI (bool GI)
{
ClientReportControlBlock_setGI (self, GI);
flagGI = true;
}
///
/// Check if RCB is reserved by a client
///
///
/// true, the RCB is reserver by a client
///
public bool GetResv ()
{
return ClientReportControlBlock_getResv (self);
}
///
/// Gets the configuration revision of the RCB
///
///
/// The conf rev.
///
public UInt32 GetConfRev ()
{
return ClientReportControlBlock_getConfRev (self);
}
///
/// Sets RESV flag. Use this to reserve (allocate) this RCB.
///
///
/// true: reserver this RCB for exclusive use
///
public void SetResv (bool resv)
{
ClientReportControlBlock_setResv (self, resv);
flagResv = true;
}
///
/// Gets the trigger options of the RCB
///
///
/// trigger options
///
public TriggerOptions GetTrgOps()
{
return (TriggerOptions) ClientReportControlBlock_getTrgOps (self);
}
///
/// Sets the trigger options of the RCB.
///
///
/// trigger options
///
public void SetTrgOps(TriggerOptions trgOps)
{
ClientReportControlBlock_setTrgOps (self, (int) trgOps);
flagTrgOps = true;
}
///
/// Gets the integrity period
///
///
/// integrity period in ms
///
public UInt32 GetIntgPd ()
{
return ClientReportControlBlock_getIntgPd (self);
}
///
/// Sets the integrity period
///
///
/// integrity period in ms
///
public void SetIntgPd (UInt32 intgPd)
{
ClientReportControlBlock_setIntgPd (self, intgPd);
flagIntgPd = true;
}
///
/// Gets the option fields.
///
///
/// The option fields
///
public ReportOptions GetOptFlds()
{
return (ReportOptions) ClientReportControlBlock_getOptFlds (self);
}
///
/// Sets the option field. Used to enable or disable optional report elements
///
///
/// Option field.
///
public void SetOptFlds(ReportOptions optFlds)
{
ClientReportControlBlock_setOptFlds (self, (int)optFlds);
flagOptFlds = true;
}
}
}
}