diff --git a/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs b/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs
index 48ec76f0..71d608a7 100644
--- a/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs
+++ b/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs
@@ -37,47 +37,47 @@ namespace IEC61850
///
/// IEC 61850 client API.
///
- namespace Client
- {
+ namespace Client
+ {
- [StructLayout(LayoutKind.Sequential)]
- public class MmsServerIdentity
- {
- public string vendorName;
- public string modelName;
- public string revision;
- }
+ [StructLayout(LayoutKind.Sequential)]
+ public class MmsServerIdentity
+ {
+ public string vendorName;
+ public string modelName;
+ public string revision;
+ }
///
/// Represents an MmsConnection object (a single connection to an MMS server)
///
- public class MmsConnection
- {
+ public class MmsConnection
+ {
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- private static extern IntPtr MmsConnection_create();
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ private static extern IntPtr MmsConnection_create();
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- private static extern void MmsConnection_destroy(IntPtr self);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ private static extern void MmsConnection_destroy(IntPtr self);
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- private static extern IntPtr MmsConnection_identify(IntPtr self, out int mmsError);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ private static extern IntPtr MmsConnection_identify(IntPtr self, out int mmsError);
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- private static extern void MmsServerIdentity_destroy(IntPtr self);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ private static extern void MmsServerIdentity_destroy(IntPtr self);
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- private static extern void MmsConnection_setLocalDetail (IntPtr self, Int32 localDetail);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ private static extern void MmsConnection_setLocalDetail(IntPtr self, Int32 localDetail);
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- private static extern Int32 MmsConnection_getLocalDetail (IntPtr self);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ private static extern Int32 MmsConnection_getLocalDetail(IntPtr self);
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr MmsConnection_readMultipleVariables(IntPtr self, out int mmsError,
string domainId, IntPtr items);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
- private static extern void MmsValue_delete (IntPtr self);
+ private static extern void MmsValue_delete(IntPtr self);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void LinkedListValueDeleteFunction(IntPtr pointer);
@@ -86,33 +86,35 @@ namespace IEC61850
private static extern void LinkedList_destroyDeep(IntPtr list, LinkedListValueDeleteFunction valueDeleteFunction);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
- private static extern IntPtr LinkedList_create ();
+ private static extern IntPtr LinkedList_create();
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
- private static extern void LinkedList_add (IntPtr self, IntPtr data);
+ private static extern void LinkedList_add(IntPtr self, IntPtr data);
- private IntPtr self = IntPtr.Zero;
- private bool selfDestroy = false;
+ private IntPtr self = IntPtr.Zero;
+ private bool selfDestroy = false;
- public MmsConnection() {
- selfDestroy = true;
+ public MmsConnection()
+ {
+ selfDestroy = true;
- self = MmsConnection_create();
- }
+ self = MmsConnection_create();
+ }
- internal MmsConnection(IntPtr mmsConnection) {
- self = mmsConnection;
- }
+ internal MmsConnection(IntPtr mmsConnection)
+ {
+ self = mmsConnection;
+ }
- ~MmsConnection ()
+ ~MmsConnection ()
{
- if (selfDestroy)
- if (self != IntPtr.Zero)
- MmsConnection_destroy(self);
+ if (selfDestroy)
+ if (self != IntPtr.Zero)
+ MmsConnection_destroy(self);
}
- private void FreeHGlobaleDeleteFunction (IntPtr pointer)
+ private void FreeHGlobaleDeleteFunction(IntPtr pointer)
{
Marshal.FreeHGlobal(pointer);
}
@@ -121,15 +123,16 @@ namespace IEC61850
/// Requests the server identity information
///
/// The server identity.
- public MmsServerIdentity GetServerIdentity ()
- {
- int mmsError;
+ public MmsServerIdentity GetServerIdentity()
+ {
+ int mmsError;
- if (self == IntPtr.Zero) {
- throw new IedConnectionException("Pointer is Zero!");
- }
+ if (self == IntPtr.Zero)
+ {
+ throw new IedConnectionException("Pointer is Zero!");
+ }
- IntPtr identity = MmsConnection_identify(self, out mmsError);
+ IntPtr identity = MmsConnection_identify(self, out mmsError);
if (mmsError != 0)
throw new IedConnectionException("Failed to read server identity", mmsError);
@@ -137,29 +140,31 @@ namespace IEC61850
if (identity == IntPtr.Zero)
throw new IedConnectionException("Failed to read server identity");
- MmsServerIdentity serverIdentity = (MmsServerIdentity)
+ MmsServerIdentity serverIdentity = (MmsServerIdentity)
Marshal.PtrToStructure(identity, typeof(MmsServerIdentity));
- MmsServerIdentity_destroy(identity);
+ MmsServerIdentity_destroy(identity);
- return serverIdentity;
- }
+ return serverIdentity;
+ }
///
/// Sets the local detail (maximum MMS PDU size)
///
/// maximum accepted MMS PDU size in bytes
- public void SetLocalDetail(int localDetail) {
- MmsConnection_setLocalDetail (self, localDetail);
- }
+ public void SetLocalDetail(int localDetail)
+ {
+ MmsConnection_setLocalDetail(self, localDetail);
+ }
///
/// Gets the local detail (maximum MMS PDU size)
///
/// maximum accepted MMS PDU size in bytes
- public int GetLocalDetail() {
- return MmsConnection_getLocalDetail (self);
- }
+ public int GetLocalDetail()
+ {
+ return MmsConnection_getLocalDetail(self);
+ }
///
/// Reads multipe MMS variables from the same domain
@@ -169,12 +174,13 @@ namespace IEC61850
/// list of variable names (in MMS notation e.g. "GGIO$ST$Ind1")
public MmsValue ReadMultipleVariables(string domainName, List variables)
{
- IntPtr linkedList = LinkedList_create ();
+ IntPtr linkedList = LinkedList_create();
- foreach (string variableName in variables) {
- IntPtr handle = System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi (variableName);
+ foreach (string variableName in variables)
+ {
+ IntPtr handle = System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(variableName);
- LinkedList_add (linkedList, handle);
+ LinkedList_add(linkedList, handle);
}
int error;
@@ -193,128 +199,131 @@ namespace IEC61850
return new MmsValue(mmsValue, true);
}
- }
+ }
- public class MmsJournalVariable
- {
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- static extern IntPtr MmsJournalVariable_getTag(IntPtr self);
+ public class MmsJournalVariable
+ {
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr MmsJournalVariable_getTag(IntPtr self);
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- static extern IntPtr MmsJournalVariable_getValue(IntPtr self);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr MmsJournalVariable_getValue(IntPtr self);
- private IntPtr self;
+ private IntPtr self;
- internal MmsJournalVariable(IntPtr self)
- {
- this.self = self;
- }
+ internal MmsJournalVariable(IntPtr self)
+ {
+ this.self = self;
+ }
- public string GetTag()
- {
- return Marshal.PtrToStringAnsi (MmsJournalVariable_getTag (self));
- }
+ public string GetTag()
+ {
+ return Marshal.PtrToStringAnsi(MmsJournalVariable_getTag(self));
+ }
- public MmsValue GetValue()
- {
- MmsValue mmsValue = new MmsValue (MmsJournalVariable_getValue (self));
+ public MmsValue GetValue()
+ {
+ MmsValue mmsValue = new MmsValue(MmsJournalVariable_getValue(self));
- return mmsValue;
- }
+ return mmsValue;
+ }
- }
+ }
- ///
- /// Represents an entry of a log
- ///
- public class MmsJournalEntry
- {
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- static extern void MmsJournalEntry_destroy(IntPtr self);
+ ///
+ /// Represents an entry of a log
+ ///
+ public class MmsJournalEntry
+ {
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern void MmsJournalEntry_destroy(IntPtr self);
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- static extern IntPtr MmsJournalEntry_getEntryID(IntPtr self);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr MmsJournalEntry_getEntryID(IntPtr self);
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- static extern IntPtr MmsJournalEntry_getOccurenceTime(IntPtr self);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr MmsJournalEntry_getOccurenceTime(IntPtr self);
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- static extern IntPtr MmsJournalEntry_getJournalVariables (IntPtr self);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr MmsJournalEntry_getJournalVariables(IntPtr self);
- /****************
+ /****************
* LinkedList
***************/
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
- static extern IntPtr LinkedList_getNext (IntPtr self);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr LinkedList_getNext(IntPtr self);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
- static extern IntPtr LinkedList_getData (IntPtr self);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr LinkedList_getData(IntPtr self);
- private IntPtr self;
- private List variables = null;
+ private IntPtr self;
+ private List variables = null;
- internal MmsJournalEntry(IntPtr self)
- {
- this.self = self;
- }
+ internal MmsJournalEntry(IntPtr self)
+ {
+ this.self = self;
+ }
- public List GetJournalVariables()
- {
- if (variables == null) {
+ public List GetJournalVariables()
+ {
+ if (variables == null)
+ {
- IntPtr linkedList = MmsJournalEntry_getJournalVariables (self);
+ IntPtr linkedList = MmsJournalEntry_getJournalVariables(self);
- IntPtr element = LinkedList_getNext (linkedList);
+ IntPtr element = LinkedList_getNext(linkedList);
- variables = new List ();
+ variables = new List();
- while (element != IntPtr.Zero) {
- MmsJournalVariable journalVariable = new MmsJournalVariable (LinkedList_getData (element));
+ while (element != IntPtr.Zero)
+ {
+ MmsJournalVariable journalVariable = new MmsJournalVariable(LinkedList_getData(element));
- variables.Add (journalVariable);
+ variables.Add(journalVariable);
- element = LinkedList_getNext (element);
- }
- }
+ element = LinkedList_getNext(element);
+ }
+ }
- return variables;
- }
+ return variables;
+ }
- public byte[] GetEntryID()
- {
- IntPtr mmsValuePtr = MmsJournalEntry_getEntryID (self);
+ public byte[] GetEntryID()
+ {
+ IntPtr mmsValuePtr = MmsJournalEntry_getEntryID(self);
- MmsValue mmsValue = new MmsValue (mmsValuePtr);
+ MmsValue mmsValue = new MmsValue(mmsValuePtr);
- byte[] octetString = mmsValue.getOctetString ();
+ byte[] octetString = mmsValue.getOctetString();
- return octetString;
- }
+ return octetString;
+ }
- public ulong GetOccurenceTime()
- {
- IntPtr mmsValuePtr = MmsJournalEntry_getOccurenceTime (self);
+ public ulong GetOccurenceTime()
+ {
+ IntPtr mmsValuePtr = MmsJournalEntry_getOccurenceTime(self);
- MmsValue mmsValue = new MmsValue (mmsValuePtr);
+ MmsValue mmsValue = new MmsValue(mmsValuePtr);
- return mmsValue.GetBinaryTimeAsUtcMs ();
- }
+ return mmsValue.GetBinaryTimeAsUtcMs();
+ }
- public void Dispose()
- {
- if (self != IntPtr.Zero) {
- MmsJournalEntry_destroy (self);
- self = IntPtr.Zero;
- }
- }
+ public void Dispose()
+ {
+ if (self != IntPtr.Zero)
+ {
+ MmsJournalEntry_destroy(self);
+ self = IntPtr.Zero;
+ }
+ }
- ~MmsJournalEntry ()
- {
- Dispose ();
- }
- }
+ ~MmsJournalEntry ()
+ {
+ Dispose();
+ }
+ }
///
/// Asynchonous service handler for the get RCB values service
@@ -323,7 +332,7 @@ namespace IEC61850
/// user provided callback parameter
/// Error code of response or timeout error in case of a response timeout
/// the report control block instance
- public delegate void GetRCBValuesHandler(UInt32 invokeId, object parameter, IedClientError err, ReportControlBlock rcb);
+ public delegate void GetRCBValuesHandler(UInt32 invokeId,object parameter,IedClientError err,ReportControlBlock rcb);
///
/// Asynchonous service handler for the set RCB values service
@@ -332,7 +341,7 @@ namespace IEC61850
/// user provided callback parameter
/// Error code of response or timeout error in case of a response timeout
/// the report control block instance
- public delegate void SetRCBValuesHandler(UInt32 invokeId, object parameter, IedClientError err, ReportControlBlock rcb);
+ public delegate void SetRCBValuesHandler(UInt32 invokeId,object parameter,IedClientError err,ReportControlBlock rcb);
///
/// Generic asynchonous service handler - used by simple services that have only success or error result
@@ -340,129 +349,129 @@ namespace IEC61850
/// The invoke ID of the request triggering this callback
/// user provided callback parameter
/// Error code of response or timeout error in case of a response timeout
- public delegate void GenericServiceHandler(UInt32 invokeId, object parameter, IedClientError err);
+ public delegate void GenericServiceHandler(UInt32 invokeId,object parameter,IedClientError err);
- ///
- /// This class acts as the entry point for the IEC 61850 client API. It represents a single
- /// (MMS) connection to a server.
- ///
+ ///
+ /// This class acts as the entry point for the IEC 61850 client API. It represents a single
+ /// (MMS) connection to a server.
+ ///
public partial class IedConnection : IDisposable
- {
- /*************
+ {
+ /*************
* MmsValue
*************/
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- static extern IntPtr MmsValue_toString (IntPtr self);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr MmsValue_toString(IntPtr self);
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- static extern float MmsValue_toFloat (IntPtr self);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern float MmsValue_toFloat(IntPtr self);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
- static extern bool MmsValue_getBoolean (IntPtr self);
+ static extern bool MmsValue_getBoolean(IntPtr self);
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- static extern UInt32 MmsValue_getBitStringAsInteger (IntPtr self);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern UInt32 MmsValue_getBitStringAsInteger(IntPtr self);
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- static extern int MmsValue_getType (IntPtr self);
-
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- static extern void MmsValue_delete (IntPtr self);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern int MmsValue_getType(IntPtr self);
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- static extern int MmsValue_getDataAccessError(IntPtr self);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern void MmsValue_delete(IntPtr self);
- /****************
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern int MmsValue_getDataAccessError(IntPtr self);
+
+ /****************
* IedConnection
***************/
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- static extern IntPtr IedConnection_create ();
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr IedConnection_create();
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- static extern IntPtr IedConnection_createWithTlsSupport (IntPtr tlsConfig);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr IedConnection_createWithTlsSupport(IntPtr tlsConfig);
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- static extern void IedConnection_destroy (IntPtr self);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern void IedConnection_destroy(IntPtr self);
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedConnection_setConnectTimeout(IntPtr self, UInt32 timeoutInMs);
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- static extern void IedConnection_connect (IntPtr self, out int error, string hostname, int tcpPort);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern void IedConnection_connect(IntPtr self, out int error, string hostname, int tcpPort);
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- static extern void IedConnection_abort (IntPtr self, out int error);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern void IedConnection_abort(IntPtr self, out int error);
+
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ private static extern void IedConnection_release(IntPtr self, out int error);
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- private static extern void IedConnection_release(IntPtr self, out int error);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ private static extern void IedConnection_close(IntPtr self);
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- private static extern void IedConnection_close(IntPtr self);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr IedConnection_readObject(IntPtr self, out int error, string objectReference, int fc);
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- static extern IntPtr IedConnection_readObject (IntPtr self, out int error, string objectReference, int fc);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern void IedConnection_writeObject(IntPtr self, out int error, string dataAttributeReference, int fc, IntPtr value);
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- static extern void IedConnection_writeObject (IntPtr self, out int error, string dataAttributeReference, int fc, IntPtr value);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr IedConnection_getDataDirectory(IntPtr self, out int error, string dataReference);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
- static extern IntPtr IedConnection_getDataDirectory (IntPtr self, out int error, string dataReference);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr IedConnection_getDataDirectoryByFC(IntPtr self, out int error, string dataReference, FunctionalConstraint fc);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
- static extern IntPtr IedConnection_getDataDirectoryByFC (IntPtr self, out int error, string dataReference, FunctionalConstraint fc);
+ static extern IntPtr IedConnection_getDataDirectoryFC(IntPtr self, out int error, string dataReference);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
- static extern IntPtr IedConnection_getDataDirectoryFC (IntPtr self, out int error, string dataReference);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr IedConnection_getLogicalNodeDirectory(IntPtr self, out int error, string logicalNodeReference, int acsiClass);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
- static extern IntPtr IedConnection_getLogicalNodeDirectory (IntPtr self, out int error, string logicalNodeReference, int acsiClass);
-
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- static extern IntPtr IedConnection_getServerDirectory (IntPtr self, out int error, [MarshalAs(UnmanagedType.I1)] bool getFileNames);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr IedConnection_getServerDirectory(IntPtr self, out int error, [MarshalAs(UnmanagedType.I1)] bool getFileNames);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedConnection_getDeviceModelFromServer(IntPtr self, out int error);
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- static extern IntPtr IedConnection_getLogicalDeviceDirectory (IntPtr self, out int error, string logicalDeviceName);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr IedConnection_getLogicalDeviceDirectory(IntPtr self, out int error, string logicalDeviceName);
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- static extern IntPtr IedConnection_getVariableSpecification(IntPtr self, out int error, string objectReference, int fc);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr IedConnection_getVariableSpecification(IntPtr self, out int error, string objectReference, int fc);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- private delegate void InternalConnectionClosedHandler (IntPtr parameter,IntPtr Iedconnection);
+ private delegate void InternalConnectionClosedHandler(IntPtr parameter,IntPtr Iedconnection);
///
/// Called when the connection is closed
///
- public delegate void ConnectionClosedHandler (IedConnection connection);
+ public delegate void ConnectionClosedHandler(IedConnection connection);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
- static extern void IedConnection_installConnectionClosedHandler (IntPtr self, InternalConnectionClosedHandler handler, IntPtr parameter);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern void IedConnection_installConnectionClosedHandler(IntPtr self, InternalConnectionClosedHandler handler, IntPtr parameter);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
- static extern IntPtr IedConnection_readDataSetValues (IntPtr self, out int error, [MarshalAs(UnmanagedType.LPStr)] string dataSetReference, IntPtr dataSet);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr IedConnection_readDataSetValues(IntPtr self, out int error, [MarshalAs(UnmanagedType.LPStr)] string dataSetReference, IntPtr dataSet);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
- static extern void IedConnection_writeDataSetValues (IntPtr self, out int error, [MarshalAs(UnmanagedType.LPStr)] string dataSetReference, IntPtr values, out IntPtr accessResults);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern void IedConnection_writeDataSetValues(IntPtr self, out int error, [MarshalAs(UnmanagedType.LPStr)] string dataSetReference, IntPtr values, out IntPtr accessResults);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
- static extern IntPtr IedConnection_createDataSet (IntPtr self, out int error, [MarshalAs(UnmanagedType.LPStr)] string dataSetReference, IntPtr dataSet);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr IedConnection_createDataSet(IntPtr self, out int error, [MarshalAs(UnmanagedType.LPStr)] string dataSetReference, IntPtr dataSet);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
- [return: MarshalAs(UnmanagedType.Bool)]
- static extern bool IedConnection_deleteDataSet (IntPtr self, out int error, string dataSetReference);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ static extern bool IedConnection_deleteDataSet(IntPtr self, out int error, string dataSetReference);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr IedConnection_getDataSetDirectory(IntPtr self, out int error, string dataSetReference, [MarshalAs(UnmanagedType.I1)] out bool isDeletable);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
- static extern IntPtr IedConnection_getMmsConnection (IntPtr self);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr IedConnection_getMmsConnection(IntPtr self);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
- static extern IntPtr MmsConnection_getIsoConnectionParameters(IntPtr mmsConnection);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr MmsConnection_getIsoConnectionParameters(IntPtr mmsConnection);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr IedConnection_getFileDirectory(IntPtr self, out int error, string directoryName);
@@ -475,38 +484,38 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedConnection_deleteFile(IntPtr self, out int error, string fileName);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
- static extern IntPtr IedConnection_queryLogAfter(IntPtr self, out int error, string logReference,
- IntPtr entryID, ulong timeStamp, [MarshalAs(UnmanagedType.I1)] out bool moreFollows);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr IedConnection_queryLogAfter(IntPtr self, out int error, string logReference,
+ IntPtr entryID, ulong timeStamp, [MarshalAs(UnmanagedType.I1)] out bool moreFollows);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
- static extern IntPtr IedConnection_queryLogByTime (IntPtr self, out int error, string logReference,
- ulong startTime, ulong endTime, [MarshalAs(UnmanagedType.I1)] out bool moreFollows);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr IedConnection_queryLogByTime(IntPtr self, out int error, string logReference,
+ ulong startTime, ulong endTime, [MarshalAs(UnmanagedType.I1)] out bool moreFollows);
- [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 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, [MarshalAs(UnmanagedType.I1)] bool singleRequest);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern void IedConnection_setRCBValues(IntPtr connection, out int error, IntPtr rcb, UInt32 parametersMask, [MarshalAs(UnmanagedType.I1)] bool singleRequest);
- [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_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);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern void IedConnection_uninstallReportHandler(IntPtr connection, string rcbReference);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int IedConnection_getState(IntPtr connection);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- private delegate void InternalStateChangedHandler (IntPtr parameter,IntPtr iedConnection, int newState);
+ private delegate void InternalStateChangedHandler(IntPtr parameter,IntPtr iedConnection,int newState);
///
/// Called when there is a change in the connection state
///
- public delegate void StateChangedHandler (IedConnection connection, IedConnectionState newState);
+ public delegate void StateChangedHandler(IedConnection connection,IedConnectionState newState);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedConnection_installStateChangedHandler(IntPtr connection, InternalStateChangedHandler handler, IntPtr parameter);
@@ -515,25 +524,25 @@ namespace IEC61850
* Async functions
*********************/
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- static extern void IedConnection_connectAsync (IntPtr self, out int error, string hostname, int tcpPort);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern void IedConnection_connectAsync(IntPtr self, out int error, string hostname, int tcpPort);
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
- static extern void IedConnection_abortAsync (IntPtr self, out int error);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern void IedConnection_abortAsync(IntPtr self, out int error);
- [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void IedConnection_releaseAsync(IntPtr self, out int error);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- private delegate void IedConnection_ReadObjectHandler (UInt32 invokeId, IntPtr parameter, int err, IntPtr value);
+ private delegate void IedConnection_ReadObjectHandler(UInt32 invokeId,IntPtr parameter,int err,IntPtr value);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32
IedConnection_readObjectAsync(IntPtr self, out int error, string objRef, int fc,
- IedConnection_ReadObjectHandler handler, IntPtr parameter);
+ IedConnection_ReadObjectHandler handler, IntPtr parameter);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- private delegate void IedConnection_WriteObjectHandler (UInt32 invokeId, IntPtr parameter, int err);
+ private delegate void IedConnection_WriteObjectHandler(UInt32 invokeId,IntPtr parameter,int err);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32
@@ -541,72 +550,72 @@ namespace IEC61850
IntPtr value, IedConnection_WriteObjectHandler handler, IntPtr parameter);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- private delegate void IedConnection_GetNameListHandler (UInt32 invokeId, IntPtr parameter, int err, IntPtr nameList, [MarshalAs(UnmanagedType.I1)] bool moreFollows);
+ private delegate void IedConnection_GetNameListHandler(UInt32 invokeId,IntPtr parameter,int err,IntPtr nameList,[MarshalAs(UnmanagedType.I1)] bool moreFollows);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32
IedConnection_getServerDirectoryAsync(IntPtr self, out int error, string continueAfter, IntPtr result,
- IedConnection_GetNameListHandler handler, IntPtr parameter);
+ IedConnection_GetNameListHandler handler, IntPtr parameter);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32
IedConnection_getLogicalDeviceVariablesAsync(IntPtr self, out int error, string ldName, string continueAfter, IntPtr result,
- IedConnection_GetNameListHandler handler, IntPtr parameter);
+ IedConnection_GetNameListHandler handler, IntPtr parameter);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32
IedConnection_getLogicalDeviceDataSetsAsync(IntPtr self, out int error, string ldName, string continueAfter, IntPtr result,
- IedConnection_GetNameListHandler handler, IntPtr parameter);
+ IedConnection_GetNameListHandler handler, IntPtr parameter);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- private delegate void IedConnection_QueryLogHandler (UInt32 invokeId, IntPtr parameter, int err, IntPtr journalEntries, [MarshalAs(UnmanagedType.I1)] bool moreFollows);
+ private delegate void IedConnection_QueryLogHandler(UInt32 invokeId,IntPtr parameter,int err,IntPtr journalEntries,[MarshalAs(UnmanagedType.I1)] bool moreFollows);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32
IedConnection_queryLogByTimeAsync(IntPtr self, out int error, string logReference,
- UInt64 startTime, UInt64 endTime, IedConnection_QueryLogHandler handler, IntPtr parameter);
+ UInt64 startTime, UInt64 endTime, IedConnection_QueryLogHandler handler, IntPtr parameter);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32
IedConnection_queryLogAfterAsync(IntPtr self, out int error, string logReference,
- IntPtr entryID, UInt64 timeStamp, IedConnection_QueryLogHandler handler, IntPtr parameter);
+ IntPtr entryID, UInt64 timeStamp, IedConnection_QueryLogHandler handler, IntPtr parameter);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- private delegate void IedConnection_GetVariableSpecificationHandler (UInt32 invokeId, IntPtr parameter, int err, IntPtr spec);
+ private delegate void IedConnection_GetVariableSpecificationHandler(UInt32 invokeId,IntPtr parameter,int err,IntPtr spec);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32
IedConnection_getVariableSpecificationAsync(IntPtr self, out int error, string dataAttributeReference,
- int fc, IedConnection_GetVariableSpecificationHandler handler, IntPtr parameter);
+ int fc, IedConnection_GetVariableSpecificationHandler handler, IntPtr parameter);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- private delegate void IedConnection_ReadDataSetHandler (UInt32 invokeId, IntPtr parameter, int err, IntPtr dataSet);
+ private delegate void IedConnection_ReadDataSetHandler(UInt32 invokeId,IntPtr parameter,int err,IntPtr dataSet);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32
IedConnection_readDataSetValuesAsync(IntPtr self, out int error, string dataSetReference, IntPtr dataSet,
- IedConnection_ReadDataSetHandler handler, IntPtr parameter);
+ IedConnection_ReadDataSetHandler handler, IntPtr parameter);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- private delegate void IedConnection_GetRCBValuesHandler (UInt32 invokeId, IntPtr parameter, int err, IntPtr rcb);
+ private delegate void IedConnection_GetRCBValuesHandler(UInt32 invokeId,IntPtr parameter,int err,IntPtr rcb);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32
IedConnection_getRCBValuesAsync(IntPtr self, out int error, string rcbReference, IntPtr updateRcb,
- IedConnection_GetRCBValuesHandler handler, IntPtr parameter);
+ IedConnection_GetRCBValuesHandler handler, IntPtr parameter);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- private delegate void IedConnection_GenericServiceHandler (UInt32 invokeId, IntPtr parameter, int err);
+ private delegate void IedConnection_GenericServiceHandler(UInt32 invokeId,IntPtr parameter,int err);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32
IedConnection_setRCBValuesAsync(IntPtr self, out int error, IntPtr rcb,
- UInt32 parametersMask, [MarshalAs(UnmanagedType.I1)] bool singleRequest, IedConnection_GenericServiceHandler handler, IntPtr parameter);
+ UInt32 parametersMask, [MarshalAs(UnmanagedType.I1)] bool singleRequest, IedConnection_GenericServiceHandler handler, IntPtr parameter);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32
IedConnection_deleteFileAsync(IntPtr self, out int error, string fileName,
- IedConnection_GenericServiceHandler handler, IntPtr parameter);
+ IedConnection_GenericServiceHandler handler, IntPtr parameter);
/********************
@@ -615,17 +624,17 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void FileDirectoryEntry_destroy(IntPtr self);
- /****************
+ /****************
* LinkedList
***************/
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
- static extern IntPtr LinkedList_getNext (IntPtr self);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr LinkedList_getNext(IntPtr self);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
- static extern IntPtr LinkedList_getData (IntPtr self);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr LinkedList_getData(IntPtr self);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
- static extern void LinkedList_destroy (IntPtr self);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern void LinkedList_destroy(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void LinkedList_destroyStatic(IntPtr self);
@@ -633,70 +642,71 @@ namespace IEC61850
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void LinkedListValueDeleteFunction(IntPtr pointer);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
- static extern void LinkedList_destroyDeep(IntPtr list, LinkedListValueDeleteFunction valueDeleteFunction);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern void LinkedList_destroyDeep(IntPtr list, LinkedListValueDeleteFunction valueDeleteFunction);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
- static extern IntPtr LinkedList_create ();
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr LinkedList_create();
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
- static extern void LinkedList_add (IntPtr self, IntPtr data);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern void LinkedList_add(IntPtr self, IntPtr data);
- private IntPtr connection = IntPtr.Zero;
+ private IntPtr connection = IntPtr.Zero;
private InternalConnectionClosedHandler connectionClosedHandler = null;
- private ConnectionClosedHandler userProvidedConnectionClosedHandler = null;
+ private ConnectionClosedHandler userProvidedConnectionClosedHandler = null;
private InternalStateChangedHandler internalStateChangedHandler = null;
private StateChangedHandler stateChangedHandler = null;
- ///
- /// Initializes a new instance of the class.
- ///
- public IedConnection ()
- {
- connection = IedConnection_create ();
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// TLS configuration to use
- public IedConnection (TLSConfiguration tlsConfig)
- {
- connection = IedConnection_createWithTlsSupport (tlsConfig.GetNativeInstance ());
- }
-
- ///
- /// 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()
- {
- if (connection != IntPtr.Zero) {
-
- IedConnection_destroy (connection);
-
- connection = IntPtr.Zero;
- }
- }
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public IedConnection()
+ {
+ connection = IedConnection_create();
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// TLS configuration to use
+ public IedConnection(TLSConfiguration tlsConfig)
+ {
+ connection = IedConnection_createWithTlsSupport(tlsConfig.GetNativeInstance());
+ }
+
+ ///
+ /// 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()
+ {
+ if (connection != IntPtr.Zero)
+ {
+
+ IedConnection_destroy(connection);
+
+ connection = IntPtr.Zero;
+ }
+ }
~IedConnection ()
{
- Dispose ();
+ Dispose();
}
private IsoConnectionParameters isoConnectionParameters = null;
- ///
- /// Gets the connection parameters
- ///
- /// The connection parameters
- public IsoConnectionParameters GetConnectionParameters ()
- {
- if (isoConnectionParameters == null)
+ ///
+ /// Gets the connection parameters
+ ///
+ /// The connection parameters
+ public IsoConnectionParameters GetConnectionParameters()
+ {
+ if (isoConnectionParameters == null)
{
IntPtr mmsConnection = IedConnection_getMmsConnection(connection);
@@ -706,15 +716,15 @@ namespace IEC61850
}
return isoConnectionParameters;
- }
+ }
- private void FreeHGlobaleDeleteFunction (IntPtr pointer)
- {
- Marshal.FreeHGlobal(pointer);
- }
+ private void FreeHGlobaleDeleteFunction(IntPtr pointer)
+ {
+ Marshal.FreeHGlobal(pointer);
+ }
- private UInt32 connectTimeout = 10000;
+ private UInt32 connectTimeout = 10000;
///
/// Gets or sets the timeout used for connection attempts.
@@ -722,10 +732,12 @@ namespace IEC61850
/// The connect timeout in milliseconds
public UInt32 ConnectTimeout
{
- get {
+ get
+ {
return connectTimeout;
}
- set {
+ set
+ {
connectTimeout = value;
}
}
@@ -736,10 +748,12 @@ namespace IEC61850
/// The maximum allowed size of an MMS PDU.
public int MaxPduSize
{
- get {
+ get
+ {
return GetMmsConnection().GetLocalDetail();
}
- set {
+ set
+ {
GetMmsConnection().SetLocalDetail(value);
}
}
@@ -748,26 +762,26 @@ namespace IEC61850
/// Gets the underlying MmsConnection instance.
///
/// The mms connection.
- public MmsConnection GetMmsConnection ()
- {
- IntPtr mmsConnectionPtr = IedConnection_getMmsConnection(connection);
+ public MmsConnection GetMmsConnection()
+ {
+ IntPtr mmsConnectionPtr = IedConnection_getMmsConnection(connection);
- return new MmsConnection(mmsConnectionPtr);
- }
+ return new MmsConnection(mmsConnectionPtr);
+ }
- /// Establish an MMS connection to a server
- /// This exception is thrown if there is a connection or service error
- public void Connect (string hostname, int tcpPort)
- {
- int error;
+ /// Establish an MMS connection to a server
+ /// This exception is thrown if there is a connection or service error
+ public void Connect(string hostname, int tcpPort)
+ {
+ int error;
IedConnection_setConnectTimeout(connection, connectTimeout);
- IedConnection_connect (connection, out error, hostname, tcpPort);
+ IedConnection_connect(connection, out error, hostname, tcpPort);
- if (error != 0)
- throw new IedConnectionException ("Connect to " + hostname + ":" + tcpPort + " failed", error);
- }
+ if (error != 0)
+ throw new IedConnectionException("Connect to " + hostname + ":" + tcpPort + " failed", error);
+ }
public void ConnectAsync(string hostname, int tcpPort)
{
@@ -775,10 +789,10 @@ namespace IEC61850
IedConnection_setConnectTimeout(connection, connectTimeout);
- IedConnection_connectAsync (connection, out error, hostname, tcpPort);
+ IedConnection_connectAsync(connection, out error, hostname, tcpPort);
if (error != 0)
- throw new IedConnectionException ("Connect to " + hostname + ":" + tcpPort + " failed", error);
+ throw new IedConnectionException("Connect to " + hostname + ":" + tcpPort + " failed", error);
}
@@ -791,578 +805,597 @@ namespace IEC61850
return (IedConnectionState)IedConnection_getState(connection);
}
- /// Establish an MMS connection to a server.
- /// This exception is thrown if there is a connection or service error.
- public void Connect (string hostname)
- {
- Connect (hostname, -1);
- }
-
- /// This exception is thrown if there is a connection or service error
- public ControlObject CreateControlObject (string objectReference)
- {
- ControlObject controlObject = new ControlObject (objectReference, connection, this);
-
- return controlObject;
- }
-
- ///
- /// Creates a new SampledValuesControlBlock instance.
- ///
- /// >
- /// This function will also read the SVCB values from the server.
- ///
- /// The new SVCB instance
- /// The object reference of the SVCB
- public SampledValuesControlBlock GetSvControlBlock (string svcbObjectReference)
- {
- return new SampledValuesControlBlock (connection, svcbObjectReference);
- }
-
- ///
- /// Creates a new SampledValuesControlBlock instance.
- ///
- /// The new GoCB instance
- /// The object reference of the GoCB
- public GooseControlBlock GetGooseControlBlock (string gocbObjectReference)
- {
- return new GooseControlBlock (gocbObjectReference, connection);
- }
-
- ///
- /// Updates the device model by quering the server.
- ///
- public void UpdateDeviceModel()
+ /// Establish an MMS connection to a server.
+ /// This exception is thrown if there is a connection or service error.
+ public void Connect(string hostname)
+ {
+ Connect(hostname, -1);
+ }
+
+ /// This exception is thrown if there is a connection or service error
+ public ControlObject CreateControlObject(string objectReference)
+ {
+ ControlObject controlObject = new ControlObject(objectReference, connection, this);
+
+ return controlObject;
+ }
+
+ ///
+ /// Creates a new SampledValuesControlBlock instance.
+ ///
+ /// >
+ /// This function will also read the SVCB values from the server.
+ ///
+ /// The new SVCB instance
+ /// The object reference of the SVCB
+ public SampledValuesControlBlock GetSvControlBlock(string svcbObjectReference)
+ {
+ return new SampledValuesControlBlock(connection, svcbObjectReference);
+ }
+
+ ///
+ /// Creates a new SampledValuesControlBlock instance.
+ ///
+ /// The new GoCB instance
+ /// The object reference of the GoCB
+ public GooseControlBlock GetGooseControlBlock(string gocbObjectReference)
+ {
+ return new GooseControlBlock(gocbObjectReference, connection);
+ }
+
+ ///
+ /// Updates the device model by quering the server.
+ ///
+ public void UpdateDeviceModel()
{
int error;
IedConnection_getDeviceModelFromServer(connection, out error);
- if (error != 0)
+ if (error != 0)
throw new IedConnectionException("UpdateDeviceModel failed", error);
}
- ///
- /// Gets the server directory (Logical devices or file objects)
- ///
- /// List of logical devices or files
- /// If set to true the file directory is returned, otherwise the LD names
- /// This exception is thrown if there is a connection or service error
- public List GetServerDirectory (bool fileDirectory = false)
- {
- int error;
+ ///
+ /// Gets the server directory (Logical devices or file objects)
+ ///
+ /// List of logical devices or files
+ /// If set to true the file directory is returned, otherwise the LD names
+ /// This exception is thrown if there is a connection or service error
+ public List GetServerDirectory(bool fileDirectory = false)
+ {
+ int error;
+
+ IntPtr linkedList = IedConnection_getServerDirectory(connection, out error, fileDirectory);
+
+ if (error != 0)
+ throw new IedConnectionException("GetDeviceDirectory failed", error);
+
+ List newList = new List();
+
+ if (fileDirectory == false)
+ {
+
+ IntPtr element = LinkedList_getNext(linkedList);
+
+ while (element != IntPtr.Zero)
+ {
+ string ld = Marshal.PtrToStringAnsi(LinkedList_getData(element));
+
+ newList.Add(ld);
+
+ element = LinkedList_getNext(element);
+ }
- IntPtr linkedList = IedConnection_getServerDirectory (connection, out error, fileDirectory);
+ LinkedList_destroy(linkedList);
+ }
+ else
+ {
- if (error != 0)
- throw new IedConnectionException ("GetDeviceDirectory failed", error);
+ IntPtr element = LinkedList_getNext(linkedList);
- List newList = new List ();
+ while (element != IntPtr.Zero)
+ {
+ IntPtr elementData = LinkedList_getData(element);
- if (fileDirectory == false) {
+ FileDirectoryEntry entry = new FileDirectoryEntry(elementData);
- IntPtr element = LinkedList_getNext (linkedList);
+ newList.Add(entry.GetFileName());
- while (element != IntPtr.Zero) {
- string ld = Marshal.PtrToStringAnsi (LinkedList_getData (element));
+ FileDirectoryEntry_destroy(elementData);
- newList.Add (ld);
+ element = LinkedList_getNext(element);
+ }
- element = LinkedList_getNext (element);
- }
+ LinkedList_destroyStatic(linkedList);
+ }
- LinkedList_destroy (linkedList);
- }
- else {
+ return newList;
+ }
- IntPtr element = LinkedList_getNext(linkedList);
+ /// This exception is thrown if there is a connection or service error
+ public List GetLogicalDeviceDirectory(string logicalDeviceName)
+ {
+ int error;
- while (element != IntPtr.Zero)
- {
- IntPtr elementData = LinkedList_getData(element);
+ IntPtr linkedList = IedConnection_getLogicalDeviceDirectory(connection, out error, logicalDeviceName);
- FileDirectoryEntry entry = new FileDirectoryEntry(elementData);
+ if (error != 0)
+ throw new IedConnectionException("GetLogicalDeviceDirectory failed", error);
- newList.Add(entry.GetFileName());
+ IntPtr element = LinkedList_getNext(linkedList);
- FileDirectoryEntry_destroy(elementData);
+ List newList = new List();
- element = LinkedList_getNext(element);
- }
+ while (element != IntPtr.Zero)
+ {
+ string ln = Marshal.PtrToStringAnsi(LinkedList_getData(element));
- LinkedList_destroyStatic(linkedList);
- }
+ newList.Add(ln);
- return newList;
- }
+ element = LinkedList_getNext(element);
+ }
- /// This exception is thrown if there is a connection or service error
- public List GetLogicalDeviceDirectory (string logicalDeviceName)
- {
- int error;
+ LinkedList_destroy(linkedList);
- IntPtr linkedList = IedConnection_getLogicalDeviceDirectory (connection, out error, logicalDeviceName);
+ return newList;
+ }
- if (error != 0)
- throw new IedConnectionException ("GetLogicalDeviceDirectory failed", error);
+ /// Get the directory of a logical node (LN)
+ /// This function returns the directory contents of a LN. Depending on the provided ACSI class
+ /// The function returns either data object references, or references of other objects like data sets,
+ /// report control blocks, ...
+ /// The object reference of a DO, SDO, or DA.
+ /// the ACSI class of the requested directory elements.
+ /// This exception is thrown if there is a connection or service error
+ public List GetLogicalNodeDirectory(string logicalNodeName, ACSIClass acsiClass)
+ {
+ int error;
- IntPtr element = LinkedList_getNext (linkedList);
+ IntPtr linkedList = IedConnection_getLogicalNodeDirectory(connection, out error, logicalNodeName, (int)acsiClass);
- List newList = new List ();
+ if (error != 0)
+ throw new IedConnectionException("GetLogicalNodeDirectory failed", error);
- while (element != IntPtr.Zero) {
- string ln = Marshal.PtrToStringAnsi (LinkedList_getData (element));
+ IntPtr element = LinkedList_getNext(linkedList);
- newList.Add (ln);
+ List newList = new List();
- element = LinkedList_getNext (element);
- }
+ while (element != IntPtr.Zero)
+ {
+ string dataObject = Marshal.PtrToStringAnsi(LinkedList_getData(element));
- LinkedList_destroy (linkedList);
+ newList.Add(dataObject);
- return newList;
- }
+ element = LinkedList_getNext(element);
+ }
- /// Get the directory of a logical node (LN)
- /// This function returns the directory contents of a LN. Depending on the provided ACSI class
- /// The function returns either data object references, or references of other objects like data sets,
- /// report control blocks, ...
- /// The object reference of a DO, SDO, or DA.
- /// the ACSI class of the requested directory elements.
- /// This exception is thrown if there is a connection or service error
- public List GetLogicalNodeDirectory (string logicalNodeName, ACSIClass acsiClass)
- {
- int error;
+ LinkedList_destroy(linkedList);
- IntPtr linkedList = IedConnection_getLogicalNodeDirectory (connection, out error, logicalNodeName, (int)acsiClass);
+ return newList;
+ }
- if (error != 0)
- throw new IedConnectionException ("GetLogicalNodeDirectory failed", error);
+ /// Get a list of attributes (with functional constraints) of a DO, SDO, or DA
+ /// The object reference of a DO, SDO, or DA.
+ /// This exception is thrown if there is a connection or service error
+ public List GetDataDirectory(string dataReference)
+ {
+ int error;
- IntPtr element = LinkedList_getNext (linkedList);
+ IntPtr linkedList = IedConnection_getDataDirectory(connection, out error, dataReference);
- List newList = new List ();
+ if (error != 0)
+ throw new IedConnectionException("GetDataDirectory failed", error);
- while (element != IntPtr.Zero) {
- string dataObject = Marshal.PtrToStringAnsi (LinkedList_getData (element));
+ IntPtr element = LinkedList_getNext(linkedList);
- newList.Add (dataObject);
+ List newList = new List();
- element = LinkedList_getNext (element);
- }
+ while (element != IntPtr.Zero)
+ {
+ string dataObject = Marshal.PtrToStringAnsi(LinkedList_getData(element));
- LinkedList_destroy (linkedList);
+ newList.Add(dataObject);
- return newList;
- }
+ element = LinkedList_getNext(element);
+ }
+
+ LinkedList_destroy(linkedList);
+
+ return newList;
+ }
+
+ /// Get the list of attributes with the specified FC of a DO, SDO, or DA
+ /// The object reference of a DO, SDO, or DA.
+ /// Functional constraint
+ /// This exception is thrown if there is a connection or service error
+ public List GetDataDirectory(string dataReference, FunctionalConstraint fc)
+ {
+ int error;
+
+ IntPtr linkedList = IedConnection_getDataDirectoryByFC(connection, out error, dataReference, fc);
+
+ if (error != 0)
+ throw new IedConnectionException("GetDataDirectory failed", error);
+
+ IntPtr element = LinkedList_getNext(linkedList);
+
+ List newList = new List();
+
+ while (element != IntPtr.Zero)
+ {
+ string dataObject = Marshal.PtrToStringAnsi(LinkedList_getData(element));
+
+ newList.Add(dataObject);
+
+ element = LinkedList_getNext(element);
+ }
+
+ LinkedList_destroy(linkedList);
+
+ return newList;
+ }
+
+ /// Get a list of attributes (with functional constraints) of a DO, SDO, or DA
+ /// This function is similar to the GetDataDirectory except that the returned element names
+ /// have the functional contraint (FC) appended.
+ /// The object reference of a DO, SDO, or DA.
+ /// This exception is thrown if there is a connection or service error
+ public List GetDataDirectoryFC(string dataReference)
+ {
+ int error;
+
+ IntPtr linkedList = IedConnection_getDataDirectoryFC(connection, out error, dataReference);
+
+ if (error != 0)
+ throw new IedConnectionException("GetDataDirectoryFC failed", error);
+
+ IntPtr element = LinkedList_getNext(linkedList);
+
+ List newList = new List();
+
+ while (element != IntPtr.Zero)
+ {
+ string dataObject = Marshal.PtrToStringAnsi(LinkedList_getData(element));
+
+ newList.Add(dataObject);
+
+ element = LinkedList_getNext(element);
+ }
+
+ LinkedList_destroy(linkedList);
+
+ return newList;
+ }
+
+ private static List WrapNativeLogQueryResult(IntPtr linkedList)
+ {
+ List journalEntries = new List();
+
+ IntPtr element = LinkedList_getNext(linkedList);
+
+ while (element != IntPtr.Zero)
+ {
+
+ MmsJournalEntry journalEntry = new MmsJournalEntry(LinkedList_getData(element));
+
+ journalEntries.Add(journalEntry);
+
+ element = LinkedList_getNext(element);
+ }
+
+ LinkedList_destroyStatic(linkedList);
+
+ return journalEntries;
+ }
+
+ ///
+ /// Queries all log entries after the entry with the given entryID and timestamp
+ ///
+ /// The list of log entries contained in the response
+ /// The object reference of the log (e.g. "simpleIOGenericIO/LLN0$EventLog")
+ /// EntryID of the last received MmsJournalEntry
+ /// Timestamp of the last received MmsJournalEntry
+ /// Indicates that more log entries are available
+ /// This exception is thrown if there is a connection or service error
+ public List QueryLogAfter(string logRef, byte[] entryID, ulong timestamp, out bool moreFollows)
+ {
+ int error;
+ bool moreFollowsVal;
+
+ MmsValue entryIdValue = new MmsValue(entryID);
+
+ IntPtr linkedList = IedConnection_queryLogAfter(connection, out error, logRef, entryIdValue.valueReference, timestamp, out moreFollowsVal);
+
+ if (error != 0)
+ throw new IedConnectionException("QueryLogAfter failed", error);
- /// Get a list of attributes (with functional constraints) of a DO, SDO, or DA
- /// The object reference of a DO, SDO, or DA.
- /// This exception is thrown if there is a connection or service error
- public List GetDataDirectory (string dataReference)
- {
- int error;
+ moreFollows = moreFollowsVal;
- IntPtr linkedList = IedConnection_getDataDirectory (connection, out error, dataReference);
+ return WrapNativeLogQueryResult(linkedList);
+ }
- if (error != 0)
- throw new IedConnectionException ("GetDataDirectory failed", error);
+ ///
+ /// Queries all log entries of the given time range
+ ///
+ /// The list of log entries contained in the response
+ /// The object reference of the log (e.g. "simpleIOGenericIO/LLN0$EventLog")
+ /// Start time of the time range
+ /// End time of the time range
+ /// Indicates that more log entries are available
+ /// This exception is thrown if there is a connection or service error
+ public List QueryLogByTime(string logRef, ulong startTime, ulong stopTime, out bool moreFollows)
+ {
+ int error;
+ bool moreFollowsVal;
- IntPtr element = LinkedList_getNext (linkedList);
+ IntPtr linkedList = IedConnection_queryLogByTime(connection, out error, logRef, startTime, stopTime, out moreFollowsVal);
- List newList = new List ();
+ if (error != 0)
+ throw new IedConnectionException("QueryLogByTime failed", error);
- while (element != IntPtr.Zero) {
- string dataObject = Marshal.PtrToStringAnsi (LinkedList_getData (element));
+ moreFollows = moreFollowsVal;
- newList.Add (dataObject);
+ return WrapNativeLogQueryResult(linkedList);
- element = LinkedList_getNext (element);
- }
+ }
- LinkedList_destroy (linkedList);
+ ///
+ /// Queries all log entries of the given time range
+ ///
+ /// The list of log entries contained in the response
+ /// The object reference of the log (e.g. "simpleIOGenericIO/LLN0$EventLog")
+ /// Start time of the time range
+ /// End time of the time range
+ /// Indicates that more log entries are available
+ /// This exception is thrown if there is a connection or service error
+ public List QueryLogByTime(string logRef, DateTime startTime, DateTime stopTime, out bool moreFollows)
+ {
+ ulong startTimeMs = LibIEC61850.DateTimeToMsTimestamp(startTime);
+ ulong stopTimeMs = LibIEC61850.DateTimeToMsTimestamp(stopTime);
- return newList;
- }
+ return QueryLogByTime(logRef, startTimeMs, stopTimeMs, out moreFollows);
+ }
- /// Get the list of attributes with the specified FC of a DO, SDO, or DA
- /// The object reference of a DO, SDO, or DA.
- /// Functional constraint
+ /// Read the variable specification (type description of a DA or FCDO
+ /// The object reference of a DA or FCDO.
+ /// The functional constraint (FC) of the object
/// This exception is thrown if there is a connection or service error
- public List GetDataDirectory (string dataReference, FunctionalConstraint fc)
+ public MmsVariableSpecification GetVariableSpecification(string objectReference, FunctionalConstraint fc)
{
int error;
- IntPtr linkedList = IedConnection_getDataDirectoryByFC (connection, out error, dataReference, fc);
+ IntPtr varSpecPtr = IedConnection_getVariableSpecification(connection, out error, objectReference, (int)fc);
if (error != 0)
- throw new IedConnectionException ("GetDataDirectory failed", error);
-
- IntPtr element = LinkedList_getNext (linkedList);
+ throw new IedConnectionException("GetVariableSpecification failed", error);
- List newList = new List ();
+ return new MmsVariableSpecification(varSpecPtr, true);
+ }
- while (element != IntPtr.Zero) {
- string dataObject = Marshal.PtrToStringAnsi (LinkedList_getData (element));
+ private IntPtr readObjectInternal(string objectReference, FunctionalConstraint fc)
+ {
+ int error;
- newList.Add (dataObject);
+ IntPtr mmsValue = IedConnection_readObject(connection, out error, objectReference, (int)fc);
- element = LinkedList_getNext (element);
- }
+ if (error != 0)
+ throw new IedConnectionException("Reading value failed", error);
- LinkedList_destroy (linkedList);
+ if (mmsValue == IntPtr.Zero)
+ throw new IedConnectionException("Variable not found on server", error);
- return newList;
+ return mmsValue;
}
- /// Get a list of attributes (with functional constraints) of a DO, SDO, or DA
- /// This function is similar to the GetDataDirectory except that the returned element names
- /// have the functional contraint (FC) appended.
- /// The object reference of a DO, SDO, or DA.
- /// This exception is thrown if there is a connection or service error
- public List GetDataDirectoryFC (string dataReference)
- {
- int error;
+ /// Read the value of a data attribute (DA) or functional constraint data object (FCDO).
+ /// The object reference of a DA or FCDO.
+ /// The functional constraint (FC) of the object
+ /// the received value as an MmsValue instance
+ /// This exception is thrown if there is a connection or service error
+ public MmsValue ReadValue(String objectReference, FunctionalConstraint fc)
+ {
+ var value = readObjectInternal(objectReference, fc);
+
+ return new MmsValue(value, true);
+ }
- IntPtr linkedList = IedConnection_getDataDirectoryFC (connection, out error, dataReference);
+ private IntPtr readObjectInternalAndCheckDataAccessError(string objectReference, FunctionalConstraint fc)
+ {
+ IntPtr mmsValue = readObjectInternal(objectReference, fc);
- if (error != 0)
- throw new IedConnectionException ("GetDataDirectoryFC failed", error);
+ if (MmsValue_getType(mmsValue) == (int)MmsType.MMS_DATA_ACCESS_ERROR)
+ {
- IntPtr element = LinkedList_getNext (linkedList);
+ int dataAccessError = MmsValue_getDataAccessError(mmsValue);
- List newList = new List ();
+ MmsValue_delete(mmsValue);
- while (element != IntPtr.Zero) {
- string dataObject = Marshal.PtrToStringAnsi (LinkedList_getData (element));
+ throw new IedConnectionException("Data access error", dataAccessError);
+ }
- newList.Add (dataObject);
+ return mmsValue;
+ }
- element = LinkedList_getNext (element);
- }
+ /// Read the value of a basic data attribute (BDA) of type boolean.
+ /// The object reference of a BDA.
+ /// The functional constraint (FC) of the object
+ /// the received boolean value
+ /// This exception is thrown if there is a connection or service error
+ public bool ReadBooleanValue(string objectReference, FunctionalConstraint fc)
+ {
+ IntPtr mmsValue = readObjectInternalAndCheckDataAccessError(objectReference, fc);
- LinkedList_destroy (linkedList);
+ if (MmsValue_getType(mmsValue) != (int)MmsType.MMS_BOOLEAN)
+ {
+ MmsValue_delete(mmsValue);
+ throw new IedConnectionException("Result is not of type boolean (MMS_BOOLEAN)", 0);
+ }
- return newList;
- }
+ bool value = MmsValue_getBoolean(mmsValue);
- private static List WrapNativeLogQueryResult(IntPtr linkedList)
- {
- List journalEntries = new List ();
+ MmsValue_delete(mmsValue);
- IntPtr element = LinkedList_getNext (linkedList);
+ return value;
+ }
- while (element != IntPtr.Zero) {
+ /// Read the value of a basic data attribute (BDA) of type float.
+ /// The object reference of a BDA.
+ /// The functional constraint (FC) of the object
+ /// This exception is thrown if there is a connection or service error
+ public float ReadFloatValue(string objectReference, FunctionalConstraint fc)
+ {
+ IntPtr mmsValue = readObjectInternalAndCheckDataAccessError(objectReference, fc);
- MmsJournalEntry journalEntry = new MmsJournalEntry(LinkedList_getData (element));
+ if (MmsValue_getType(mmsValue) != (int)MmsType.MMS_FLOAT)
+ {
+ MmsValue_delete(mmsValue);
+ throw new IedConnectionException("Result is not of type float (MMS_FLOAT)", 0);
+ }
- journalEntries.Add (journalEntry);
+ float value = MmsValue_toFloat(mmsValue);
- element = LinkedList_getNext (element);
- }
+ MmsValue_delete(mmsValue);
- LinkedList_destroyStatic (linkedList);
+ return value;
+ }
- return journalEntries;
- }
+ /// Read the value of a basic data attribute (BDA) of type string (VisibleString or MmsString).
+ /// The object reference of a BDA.
+ /// The functional constraint (FC) of the object
+ /// This exception is thrown if there is a connection or service error
+ public string ReadStringValue(string objectReference, FunctionalConstraint fc)
+ {
+ IntPtr mmsValue = readObjectInternalAndCheckDataAccessError(objectReference, fc);
- ///
- /// Queries all log entries after the entry with the given entryID and timestamp
- ///
- /// The list of log entries contained in the response
- /// The object reference of the log (e.g. "simpleIOGenericIO/LLN0$EventLog")
- /// EntryID of the last received MmsJournalEntry
- /// Timestamp of the last received MmsJournalEntry
- /// Indicates that more log entries are available
- /// This exception is thrown if there is a connection or service error
- public List QueryLogAfter(string logRef, byte[] entryID, ulong timestamp, out bool moreFollows)
- {
- int error;
- bool moreFollowsVal;
+ if (!((MmsValue_getType(mmsValue) == (int)MmsType.MMS_VISIBLE_STRING) || (MmsValue_getType(mmsValue) == (int)MmsType.MMS_STRING)))
+ {
+ MmsValue_delete(mmsValue);
+ throw new IedConnectionException("Result is not of type string", 0);
+ }
- MmsValue entryIdValue = new MmsValue (entryID);
+ IntPtr ptr = MmsValue_toString(mmsValue);
- IntPtr linkedList = IedConnection_queryLogAfter (connection, out error, logRef, entryIdValue.valueReference, timestamp, out moreFollowsVal);
+ string returnString = Marshal.PtrToStringAnsi(ptr);
- if (error != 0)
- throw new IedConnectionException ("QueryLogAfter failed", error);
+ MmsValue_delete(mmsValue);
- moreFollows = moreFollowsVal;
+ return returnString;
+ }
- return WrapNativeLogQueryResult(linkedList);
- }
+ /// Read the value of a basic data attribute (BDA) of type quality.
+ /// The object reference of a BDA.
+ /// The functional constraint (FC) of the object
+ /// This exception is thrown if there is a connection or service error
+ public Quality ReadQualityValue(string objectReference, FunctionalConstraint fc)
+ {
+ IntPtr mmsValue = readObjectInternalAndCheckDataAccessError(objectReference, fc);
- ///
- /// Queries all log entries of the given time range
- ///
- /// The list of log entries contained in the response
- /// The object reference of the log (e.g. "simpleIOGenericIO/LLN0$EventLog")
- /// Start time of the time range
- /// End time of the time range
- /// Indicates that more log entries are available
- /// This exception is thrown if there is a connection or service error
- public List QueryLogByTime(string logRef, ulong startTime, ulong stopTime, out bool moreFollows)
- {
- int error;
- bool moreFollowsVal;
+ if (MmsValue_getType(mmsValue) == (int)MmsType.MMS_BIT_STRING)
+ {
+ int bitStringValue = (int)MmsValue_getBitStringAsInteger(mmsValue);
- IntPtr linkedList = IedConnection_queryLogByTime (connection, out error, logRef, startTime, stopTime, out moreFollowsVal);
+ MmsValue_delete(mmsValue);
+ return new Quality(bitStringValue);
+ }
+ else
+ {
+ MmsValue_delete(mmsValue);
+ throw new IedConnectionException("Result is not of type bit string(Quality)", 0);
+ }
+ }
- if (error != 0)
- throw new IedConnectionException ("QueryLogByTime failed", error);
+ /// Read the value of a basic data attribute (BDA) of type bit string.
+ /// The object reference of a BDA.
+ /// The functional constraint (FC) of the object
+ /// This exception is thrown if there is a connection or service error
+ public int ReadBitStringValue(string objectReference, FunctionalConstraint fc)
+ {
+ IntPtr mmsValue = readObjectInternalAndCheckDataAccessError(objectReference, fc);
- moreFollows = moreFollowsVal;
+ if (MmsValue_getType(mmsValue) == (int)MmsType.MMS_BIT_STRING)
+ {
+ int bitStringValue = (int)MmsValue_getBitStringAsInteger(mmsValue);
- return WrapNativeLogQueryResult(linkedList);
+ MmsValue_delete(mmsValue);
+ return bitStringValue;
+ }
+ else
+ {
+ MmsValue_delete(mmsValue);
+ throw new IedConnectionException("Result is not of type bit string", 0);
+ }
+ }
- }
+ /// Read the value of a basic data attribute (BDA) of type timestamp (MMS_UTC_TIME).
+ /// The object reference of a BDA.
+ /// The functional constraint (FC) of the object
+ /// This exception is thrown if there is a connection or service error
+ public Timestamp ReadTimestampValue(string objectReference, FunctionalConstraint fc)
+ {
+ var mmsValuePtr = readObjectInternalAndCheckDataAccessError(objectReference, fc);
- ///
- /// Queries all log entries of the given time range
- ///
- /// The list of log entries contained in the response
- /// The object reference of the log (e.g. "simpleIOGenericIO/LLN0$EventLog")
- /// Start time of the time range
- /// End time of the time range
- /// Indicates that more log entries are available
- /// This exception is thrown if there is a connection or service error
- public List QueryLogByTime(string logRef, DateTime startTime, DateTime stopTime, out bool moreFollows)
- {
- ulong startTimeMs = LibIEC61850.DateTimeToMsTimestamp (startTime);
- ulong stopTimeMs = LibIEC61850.DateTimeToMsTimestamp (stopTime);
+ var mmsValue = new MmsValue(mmsValuePtr, true);
- return QueryLogByTime (logRef, startTimeMs, stopTimeMs, out moreFollows);
- }
+ if (mmsValue.GetType() == MmsType.MMS_UTC_TIME)
+ return new Timestamp(mmsValue);
+ else
+ throw new IedConnectionException("Result is not of type timestamp (MMS_UTC_TIME)", 0);
+ }
- /// Read the variable specification (type description of a DA or FCDO
- /// The object reference of a DA or FCDO.
- /// The functional constraint (FC) of the object
- /// This exception is thrown if there is a connection or service error
- public MmsVariableSpecification GetVariableSpecification (string objectReference, FunctionalConstraint fc)
- {
- int error;
+ /// Read the value of a basic data attribute (BDA) of type integer (MMS_INTEGER).
+ /// This function should also be used if enumerations are beeing read. Because
+ /// enumerations are mapped to integer types for the MMS mapping
+ /// The object reference of a BDA.
+ /// The functional constraint (FC) of the object
+ /// This exception is thrown if there is a connection or service error
+ public Int64 ReadIntegerValue(string objectReference, FunctionalConstraint fc)
+ {
+ var mmsValuePtr = readObjectInternalAndCheckDataAccessError(objectReference, fc);
- IntPtr varSpecPtr = IedConnection_getVariableSpecification(connection, out error, objectReference, (int) fc);
+ var mmsValue = new MmsValue(mmsValuePtr, true);
- if (error != 0)
- throw new IedConnectionException ("GetVariableSpecification failed", error);
+ if (mmsValue.GetType() == MmsType.MMS_INTEGER)
+ return mmsValue.ToInt64();
+ else
+ throw new IedConnectionException("Result is not of type integer (MMS_INTEGER)", 0);
+ }
- return new MmsVariableSpecification(varSpecPtr, true);
- }
+ /// Write the value of a data attribute (DA) or functional constraint data object (FCDO).
+ /// This function can be used to write simple or complex variables (setpoints, parameters, descriptive values...)
+ /// of the server.
+ /// The object reference of a BDA.
+ /// The functional constraint (FC) of the object
+ /// MmsValue object representing asimple or complex variable data
+ /// This exception is thrown if there is a connection or service error
+ public void WriteValue(string objectReference, FunctionalConstraint fc, MmsValue value)
+ {
+ int error;
- private IntPtr readObjectInternal (string objectReference, FunctionalConstraint fc)
- {
- int error;
+ IedConnection_writeObject(connection, out error, objectReference, (int)fc, value.valueReference);
- IntPtr mmsValue = IedConnection_readObject (connection, out error, objectReference, (int)fc);
+ if (error != 0)
+ throw new IedConnectionException("Write value failed", error);
+ }
- if (error != 0)
- throw new IedConnectionException ("Reading value failed", error);
+ /// Delete file
+ /// The name of the file.
+ /// This exception is thrown if there is a connection or service error
+ public void DeleteFile(string fileName)
+ {
+ int error;
+ IedConnection_deleteFile(connection, out error, fileName);
- if (mmsValue == IntPtr.Zero)
- throw new IedConnectionException ("Variable not found on server", error);
-
- return mmsValue;
- }
-
- /// Read the value of a data attribute (DA) or functional constraint data object (FCDO).
- /// The object reference of a DA or FCDO.
- /// The functional constraint (FC) of the object
- /// the received value as an MmsValue instance
- /// This exception is thrown if there is a connection or service error
- public MmsValue ReadValue (String objectReference, FunctionalConstraint fc)
- {
- var value = readObjectInternal (objectReference, fc);
-
- return new MmsValue (value, true);
- }
+ if (error != 0)
+ throw new IedConnectionException("Deleting file " + fileName + " failed", error);
+ }
- private IntPtr readObjectInternalAndCheckDataAccessError(string objectReference, FunctionalConstraint fc)
- {
- IntPtr mmsValue = readObjectInternal (objectReference, fc);
-
- if (MmsValue_getType(mmsValue) == (int) MmsType.MMS_DATA_ACCESS_ERROR) {
-
- int dataAccessError = MmsValue_getDataAccessError (mmsValue);
-
- MmsValue_delete (mmsValue);
-
- throw new IedConnectionException ("Data access error", dataAccessError);
- }
-
- return mmsValue;
- }
-
- /// Read the value of a basic data attribute (BDA) of type boolean.
- /// The object reference of a BDA.
- /// The functional constraint (FC) of the object
- /// the received boolean value
- /// This exception is thrown if there is a connection or service error
- public bool ReadBooleanValue (string objectReference, FunctionalConstraint fc)
- {
- IntPtr mmsValue = readObjectInternalAndCheckDataAccessError (objectReference, fc);
-
- if (MmsValue_getType (mmsValue) != (int) MmsType.MMS_BOOLEAN) {
- MmsValue_delete (mmsValue);
- throw new IedConnectionException ("Result is not of type boolean (MMS_BOOLEAN)", 0);
- }
-
- bool value = MmsValue_getBoolean (mmsValue);
-
- MmsValue_delete (mmsValue);
-
- return value;
- }
-
- /// Read the value of a basic data attribute (BDA) of type float.
- /// The object reference of a BDA.
- /// The functional constraint (FC) of the object
- /// This exception is thrown if there is a connection or service error
- public float ReadFloatValue (string objectReference, FunctionalConstraint fc)
- {
- IntPtr mmsValue = readObjectInternalAndCheckDataAccessError (objectReference, fc);
-
- if (MmsValue_getType (mmsValue) != (int)MmsType.MMS_FLOAT) {
- MmsValue_delete (mmsValue);
- throw new IedConnectionException ("Result is not of type float (MMS_FLOAT)", 0);
- }
-
- float value = MmsValue_toFloat (mmsValue);
-
- MmsValue_delete (mmsValue);
-
- return value;
- }
-
- /// Read the value of a basic data attribute (BDA) of type string (VisibleString or MmsString).
- /// The object reference of a BDA.
- /// The functional constraint (FC) of the object
- /// This exception is thrown if there is a connection or service error
- public string ReadStringValue (string objectReference, FunctionalConstraint fc)
- {
- IntPtr mmsValue = readObjectInternalAndCheckDataAccessError (objectReference, fc);
-
- if (!((MmsValue_getType (mmsValue) == (int)MmsType.MMS_VISIBLE_STRING) || (MmsValue_getType (mmsValue) == (int)MmsType.MMS_STRING))) {
- MmsValue_delete (mmsValue);
- throw new IedConnectionException ("Result is not of type string", 0);
- }
-
- IntPtr ptr = MmsValue_toString (mmsValue);
-
- string returnString = Marshal.PtrToStringAnsi (ptr);
-
- MmsValue_delete (mmsValue);
-
- return returnString;
- }
-
- /// Read the value of a basic data attribute (BDA) of type quality.
- /// The object reference of a BDA.
- /// The functional constraint (FC) of the object
- /// This exception is thrown if there is a connection or service error
- public Quality ReadQualityValue (string objectReference, FunctionalConstraint fc)
- {
- IntPtr mmsValue = readObjectInternalAndCheckDataAccessError (objectReference, fc);
-
- if (MmsValue_getType (mmsValue) == (int)MmsType.MMS_BIT_STRING) {
- int bitStringValue = (int)MmsValue_getBitStringAsInteger (mmsValue);
-
- MmsValue_delete (mmsValue);
- return new Quality (bitStringValue);
- } else {
- MmsValue_delete (mmsValue);
- throw new IedConnectionException ("Result is not of type bit string(Quality)", 0);
- }
- }
-
- /// Read the value of a basic data attribute (BDA) of type bit string.
- /// The object reference of a BDA.
- /// The functional constraint (FC) of the object
- /// This exception is thrown if there is a connection or service error
- public int ReadBitStringValue (string objectReference, FunctionalConstraint fc)
- {
- IntPtr mmsValue = readObjectInternalAndCheckDataAccessError (objectReference, fc);
-
- if (MmsValue_getType (mmsValue) == (int)MmsType.MMS_BIT_STRING) {
- int bitStringValue = (int)MmsValue_getBitStringAsInteger (mmsValue);
-
- MmsValue_delete (mmsValue);
- return bitStringValue;
- } else {
- MmsValue_delete (mmsValue);
- throw new IedConnectionException ("Result is not of type bit string", 0);
- }
- }
-
- /// Read the value of a basic data attribute (BDA) of type timestamp (MMS_UTC_TIME).
- /// The object reference of a BDA.
- /// The functional constraint (FC) of the object
- /// This exception is thrown if there is a connection or service error
- public Timestamp ReadTimestampValue (string objectReference, FunctionalConstraint fc)
- {
- var mmsValuePtr = readObjectInternalAndCheckDataAccessError (objectReference, fc);
-
- var mmsValue = new MmsValue (mmsValuePtr, true);
-
- if (mmsValue.GetType () == MmsType.MMS_UTC_TIME)
- return new Timestamp (mmsValue);
- else
- throw new IedConnectionException ("Result is not of type timestamp (MMS_UTC_TIME)", 0);
- }
-
- /// Read the value of a basic data attribute (BDA) of type integer (MMS_INTEGER).
- /// This function should also be used if enumerations are beeing read. Because
- /// enumerations are mapped to integer types for the MMS mapping
- /// The object reference of a BDA.
- /// The functional constraint (FC) of the object
- /// This exception is thrown if there is a connection or service error
- public Int64 ReadIntegerValue (string objectReference, FunctionalConstraint fc)
- {
- var mmsValuePtr = readObjectInternalAndCheckDataAccessError (objectReference, fc);
-
- var mmsValue = new MmsValue (mmsValuePtr, true);
-
- if (mmsValue.GetType () == MmsType.MMS_INTEGER)
- return mmsValue.ToInt64 ();
- else
- throw new IedConnectionException ("Result is not of type integer (MMS_INTEGER)", 0);
- }
-
- /// Write the value of a data attribute (DA) or functional constraint data object (FCDO).
- /// This function can be used to write simple or complex variables (setpoints, parameters, descriptive values...)
- /// of the server.
- /// The object reference of a BDA.
- /// The functional constraint (FC) of the object
- /// MmsValue object representing asimple or complex variable data
- /// This exception is thrown if there is a connection or service error
- public void WriteValue (string objectReference, FunctionalConstraint fc, MmsValue value)
- {
- int error;
-
- IedConnection_writeObject (connection, out error, objectReference, (int)fc, value.valueReference);
-
- if (error != 0)
- throw new IedConnectionException ("Write value failed", error);
- }
-
- /// Delete file
- /// The name of the file.
- /// This exception is thrown if there is a connection or service error
- public void DeleteFile (string fileName)
- {
- int error;
- IedConnection_deleteFile (connection, out error, fileName);
-
- if (error != 0)
- throw new IedConnectionException ("Deleting file " + fileName + " failed", error);
- }
-
- private void nativeGenericServiceHandler (UInt32 invokeId, IntPtr parameter, int err)
+ private void nativeGenericServiceHandler(UInt32 invokeId, IntPtr parameter, int err)
{
GCHandle handle = GCHandle.FromIntPtr(parameter);
- Tuple callbackInfo = handle.Target as Tuple;
+ Tuple callbackInfo = handle.Target as Tuple;
GenericServiceHandler handler = callbackInfo.Item1;
object handlerParameter = callbackInfo.Item2;
@@ -1399,20 +1432,20 @@ namespace IEC61850
/// Read the content of a file directory.
/// The name of the directory.
/// This exception is thrown if there is a connection or service error
- public List GetFileDirectory(string directoryName)
+ public List GetFileDirectory(string directoryName)
{
int error;
IntPtr fileEntryList = IedConnection_getFileDirectory(connection, out error, directoryName);
- if (error != 0)
+ if (error != 0)
throw new IedConnectionException("Reading file directory failed", error);
List fileDirectory = new List();
IntPtr element = LinkedList_getNext(fileEntryList);
- while (element != IntPtr.Zero)
+ while (element != IntPtr.Zero)
{
IntPtr elementData = LinkedList_getData(element);
@@ -1467,33 +1500,33 @@ namespace IEC61850
return fileDirectory;
}
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
- private delegate bool InternalIedClientGetFileHandler(IntPtr parameter, IntPtr buffer, UInt32 bytesRead);
+ private delegate bool InternalIedClientGetFileHandler(IntPtr parameter,IntPtr buffer,UInt32 bytesRead);
- private bool iedClientGetFileHandler(IntPtr parameter, IntPtr buffer, UInt32 bytesRead)
+ private bool iedClientGetFileHandler(IntPtr parameter, IntPtr buffer, UInt32 bytesRead)
{
GCHandle handle = GCHandle.FromIntPtr(parameter);
- GetFileCallback getFileCallback = (GetFileCallback) handle.Target;
+ GetFileCallback getFileCallback = (GetFileCallback)handle.Target;
byte[] bytes = new byte[bytesRead];
- Marshal.Copy(buffer, bytes, 0, (int) bytesRead);
+ Marshal.Copy(buffer, bytes, 0, (int)bytesRead);
return getFileCallback.handler(getFileCallback.parameter, bytes);
}
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 IedConnection_getFile(IntPtr self, out int error, string fileName, InternalIedClientGetFileHandler handler,
- IntPtr handlerParameter);
+ IntPtr handlerParameter);
- public delegate bool GetFileHandler(object parameter, byte[] data);
+ public delegate bool GetFileHandler(object parameter,byte[] data);
- private class GetFileCallback
+ private class GetFileCallback
{
- public GetFileCallback(GetFileHandler handler, object parameter)
+ public GetFileCallback(GetFileHandler handler, object parameter)
{
this.handler = handler;
this.parameter = parameter;
@@ -1503,20 +1536,20 @@ namespace IEC61850
public object parameter;
}
- ///
- /// Download a file from the server.
- ///
- ///
- /// File name of the file (full path)
- ///
- ///
- /// Callback handler that is invoked for each chunk of the file received
- ///
- ///
- /// User provided parameter that is passed to the callback handler
- ///
+ ///
+ /// Download a file from the server.
+ ///
+ ///
+ /// File name of the file (full path)
+ ///
+ ///
+ /// Callback handler that is invoked for each chunk of the file received
+ ///
+ ///
+ /// User provided parameter that is passed to the callback handler
+ ///
/// This exception is thrown if there is a connection or service error
- public void GetFile(string fileName, GetFileHandler handler, object parameter)
+ public void GetFile(string fileName, GetFileHandler handler, object parameter)
{
int error;
@@ -1527,7 +1560,7 @@ namespace IEC61850
IedConnection_getFile(connection, out error, fileName, new InternalIedClientGetFileHandler(iedClientGetFileHandler),
GCHandle.ToIntPtr(handle));
- if (error != 0)
+ if (error != 0)
throw new IedConnectionException("Error reading file", error);
handle.Free();
@@ -1535,8 +1568,8 @@ namespace IEC61850
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
- private delegate bool IedConnection_GetFileAsyncHandler (UInt32 invokeId, IntPtr parameter, int err, UInt32 originalInvokeId,
- IntPtr buffer, UInt32 bytesRead, bool moreFollows);
+ private delegate bool IedConnection_GetFileAsyncHandler(UInt32 invokeId,IntPtr parameter,int err,UInt32 originalInvokeId,
+ IntPtr buffer,UInt32 bytesRead,bool moreFollows);
///
/// Callback handler for the asynchronous get file service. Will be invoked for each chunk of received data
@@ -1547,20 +1580,20 @@ namespace IEC61850
/// the invokeId of the first (file open) request
/// the file data received with the last response, or null if no file data available
/// indicates that more file data follows
- public delegate bool GetFileAsyncHandler(UInt32 invokeId, object parameter, IedClientError err, UInt32 originalInvokeId, byte[] buffer, bool moreFollows);
+ public delegate bool GetFileAsyncHandler(UInt32 invokeId,object parameter,IedClientError err,UInt32 originalInvokeId,byte[] buffer,bool moreFollows);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32
IedConnection_getFileAsync(IntPtr self, out int error, string fileName, IedConnection_GetFileAsyncHandler handler,
- IntPtr parameter);
+ IntPtr parameter);
private bool nativeGetFileAsyncHandler(UInt32 invokeId, IntPtr parameter, int err, UInt32 originalInvokeId,
- IntPtr buffer, UInt32 bytesRead, bool moreFollows)
+ IntPtr buffer, UInt32 bytesRead, bool moreFollows)
{
GCHandle handle = GCHandle.FromIntPtr(parameter);
- Tuple callbackInfo = handle.Target as Tuple;
+ Tuple callbackInfo = handle.Target as Tuple;
GetFileAsyncHandler handler = callbackInfo.Item1;
object handlerParameter = callbackInfo.Item2;
@@ -1575,7 +1608,7 @@ namespace IEC61850
{
bytes = new byte[bytesRead];
- Marshal.Copy(buffer, bytes, 0, (int) bytesRead);
+ Marshal.Copy(buffer, bytes, 0, (int)bytesRead);
}
return handler(invokeId, handlerParameter, clientError, originalInvokeId, bytes, moreFollows);
@@ -1617,21 +1650,21 @@ namespace IEC61850
- ///
- /// Abort (close) the connection.
- ///
- /// This function will send an abort request to the server. This will immediately interrupt the
- /// connection.
- /// This exception is thrown if there is a connection or service error
- public void Abort ()
- {
- int error;
+ ///
+ /// Abort (close) the connection.
+ ///
+ /// This function will send an abort request to the server. This will immediately interrupt the
+ /// connection.
+ /// This exception is thrown if there is a connection or service error
+ public void Abort()
+ {
+ int error;
- IedConnection_abort (connection, out error);
+ IedConnection_abort(connection, out error);
- if (error != 0)
- throw new IedConnectionException ("Abort failed", error);
- }
+ if (error != 0)
+ throw new IedConnectionException("Abort failed", error);
+ }
///
/// Abort (close) the connection - asynchronous version
@@ -1639,31 +1672,31 @@ namespace IEC61850
/// This function will send an abort request to the server. This will immediately interrupt the
/// connection.
/// This exception is thrown if there is a connection or service error
- public void AbortAsync ()
+ public void AbortAsync()
{
int error;
- IedConnection_abortAsync (connection, out error);
+ IedConnection_abortAsync(connection, out error);
if (error != 0)
- throw new IedConnectionException ("Abort failed", error);
+ throw new IedConnectionException("Abort failed", error);
}
- ///
- /// Release (close) the connection.
- ///
- /// This function will send an release request to the server. The function will block until the
- /// connection is released or an error occured.
- /// This exception is thrown if there is a connection or service error
- public void Release ()
- {
- int error;
+ ///
+ /// Release (close) the connection.
+ ///
+ /// This function will send an release request to the server. The function will block until the
+ /// connection is released or an error occured.
+ /// This exception is thrown if there is a connection or service error
+ public void Release()
+ {
+ int error;
- IedConnection_release(connection, out error);
+ IedConnection_release(connection, out error);
- if (error != 0)
- throw new IedConnectionException ("Release failed", error);
- }
+ if (error != 0)
+ throw new IedConnectionException("Release failed", error);
+ }
///
/// Release (close) the connection - asynchronous version
@@ -1671,52 +1704,52 @@ namespace IEC61850
/// This function will send an release request to the server. The function will block until the
/// connection is released or an error occured.
/// This exception is thrown if there is a connection or service error
- public void ReleaseAsync ()
+ public void ReleaseAsync()
{
int error;
IedConnection_releaseAsync(connection, out error);
if (error != 0)
- throw new IedConnectionException ("Release failed", error);
- }
-
- ///
- /// Immediately close the connection.
- ///
- /// This function will close the connnection to the server by closing the TCP connection.
- /// The client will not send an abort or release request as required by the specification!
- /// This exception is thrown if there is a connection or service error
- public void Close ()
- {
- IedConnection_close(connection);
- }
-
- private void MyConnectionClosedHandler (IntPtr parameter, IntPtr self)
- {
- if (userProvidedConnectionClosedHandler != null)
- userProvidedConnectionClosedHandler (this);
- }
-
- ///
- /// Install a callback handler that will be invoked if the connection is closed.
- ///
- /// The handler is called when the connection is closed no matter if the connection was closed
- /// by the client or by the server. Any new call to this function will replace the callback handler installed
- /// by a prior function call.
- /// The user provided callback handler
- /// This exception is thrown if there is a connection or service error
+ throw new IedConnectionException("Release failed", error);
+ }
+
+ ///
+ /// Immediately close the connection.
+ ///
+ /// This function will close the connnection to the server by closing the TCP connection.
+ /// The client will not send an abort or release request as required by the specification!
+ /// This exception is thrown if there is a connection or service error
+ public void Close()
+ {
+ IedConnection_close(connection);
+ }
+
+ private void MyConnectionClosedHandler(IntPtr parameter, IntPtr self)
+ {
+ if (userProvidedConnectionClosedHandler != null)
+ userProvidedConnectionClosedHandler(this);
+ }
+
+ ///
+ /// Install a callback handler that will be invoked if the connection is closed.
+ ///
+ /// The handler is called when the connection is closed no matter if the connection was closed
+ /// by the client or by the server. Any new call to this function will replace the callback handler installed
+ /// by a prior function call.
+ /// The user provided callback handler
+ /// This exception is thrown if there is a connection or service error
[Obsolete("ConnectionClosedHandler is deprecated, please use ConnectionEventHandler instead")]
- public void InstallConnectionClosedHandler (ConnectionClosedHandler handler)
- {
+ public void InstallConnectionClosedHandler(ConnectionClosedHandler handler)
+ {
if (connectionClosedHandler == null)
{
connectionClosedHandler = new InternalConnectionClosedHandler(MyConnectionClosedHandler);
- IedConnection_installConnectionClosedHandler (connection, connectionClosedHandler, connection);
+ IedConnection_installConnectionClosedHandler(connection, connectionClosedHandler, connection);
}
- userProvidedConnectionClosedHandler = handler;
- }
+ userProvidedConnectionClosedHandler = handler;
+ }
private void MyStateChangedHandler(IntPtr parameter, IntPtr IedConnection, int newState)
{
@@ -1728,7 +1761,7 @@ namespace IEC61850
/// Sets the handler for StateChanged events
///
/// The state changed event handler
- public void InstallStateChangedHandler (StateChangedHandler handler)
+ public void InstallStateChangedHandler(StateChangedHandler handler)
{
stateChangedHandler = handler;
@@ -1758,139 +1791,143 @@ namespace IEC61850
/// received values.
/// The object reference of the data set
/// This exception is thrown if there is a connection or service error
- public DataSet GetDataSetValues (string dataSetReference)
+ public DataSet GetDataSetValues(string dataSetReference)
{
return ReadDataSetValues(dataSetReference, null);
}
- ///
- /// Read the values of a data set (GetDataSetValues service).
- ///
- /// This function will invoke a readDataSetValues service and return a new DataSet value containing the
- /// received values. If an existing instance of DataSet is provided to the function the existing instance will be
- /// updated by the new values.
- /// The object reference of the data set
- /// The object reference of an existing data set instance or null
- /// a DataSet instance containing the received values
- /// This exception is thrown if there is a connection or service error
- public DataSet ReadDataSetValues (string dataSetReference, DataSet dataSet)
- {
- IntPtr nativeClientDataSet = IntPtr.Zero;
-
- if (dataSet != null)
- nativeClientDataSet = dataSet.getNativeInstance ();
+ ///
+ /// Read the values of a data set (GetDataSetValues service).
+ ///
+ /// This function will invoke a readDataSetValues service and return a new DataSet value containing the
+ /// received values. If an existing instance of DataSet is provided to the function the existing instance will be
+ /// updated by the new values.
+ /// The object reference of the data set
+ /// The object reference of an existing data set instance or null
+ /// a DataSet instance containing the received values
+ /// This exception is thrown if there is a connection or service error
+ public DataSet ReadDataSetValues(string dataSetReference, DataSet dataSet)
+ {
+ IntPtr nativeClientDataSet = IntPtr.Zero;
+
+ if (dataSet != null)
+ nativeClientDataSet = dataSet.getNativeInstance();
- int error;
+ int error;
- nativeClientDataSet = IedConnection_readDataSetValues (connection, out error, dataSetReference, nativeClientDataSet);
+ nativeClientDataSet = IedConnection_readDataSetValues(connection, out error, dataSetReference, nativeClientDataSet);
- if (error != 0)
- throw new IedConnectionException ("Reading data set failed", error);
+ if (error != 0)
+ throw new IedConnectionException("Reading data set failed", error);
- if (dataSet == null)
- dataSet = new DataSet (nativeClientDataSet);
+ if (dataSet == null)
+ dataSet = new DataSet(nativeClientDataSet);
- return dataSet;
- }
+ return dataSet;
+ }
- ///
- /// Writes the values of a data set (SetDataSetValues service).
- ///
- /// The list of access results
- /// The object reference of the data set
- /// The new values for the data set members. The values have to be of the same number and type as the data set members
- public List WriteDataSetValues(string dataSetReference, List values)
- {
- int error;
- IntPtr accessResults = IntPtr.Zero;
+ ///
+ /// Writes the values of a data set (SetDataSetValues service).
+ ///
+ /// The list of access results
+ /// The object reference of the data set
+ /// The new values for the data set members. The values have to be of the same number and type as the data set members
+ public List WriteDataSetValues(string dataSetReference, List values)
+ {
+ int error;
+ IntPtr accessResults = IntPtr.Zero;
- IntPtr valueList = LinkedList_create ();
+ IntPtr valueList = LinkedList_create();
- foreach (MmsValue mmsValue in values) {
- LinkedList_add (valueList, mmsValue.valueReference);
- }
+ foreach (MmsValue mmsValue in values)
+ {
+ LinkedList_add(valueList, mmsValue.valueReference);
+ }
- IedConnection_writeDataSetValues (connection, out error, dataSetReference, valueList, out accessResults);
+ IedConnection_writeDataSetValues(connection, out error, dataSetReference, valueList, out accessResults);
- LinkedList_destroyStatic (valueList);
+ LinkedList_destroyStatic(valueList);
- /* handle access results */
+ /* handle access results */
- List accessResultList = null;
+ List accessResultList = null;
- if (accessResults != IntPtr.Zero) {
+ if (accessResults != IntPtr.Zero)
+ {
- IntPtr element = LinkedList_getNext (accessResults);
+ IntPtr element = LinkedList_getNext(accessResults);
- while (element != IntPtr.Zero) {
- IntPtr elementData = LinkedList_getData (element);
+ while (element != IntPtr.Zero)
+ {
+ IntPtr elementData = LinkedList_getData(element);
- MmsValue accessResultValue = new MmsValue (elementData, true);
+ MmsValue accessResultValue = new MmsValue(elementData, true);
- MmsDataAccessError dataAccessError = accessResultValue.GetDataAccessError ();
+ MmsDataAccessError dataAccessError = accessResultValue.GetDataAccessError();
- accessResultList.Add (dataAccessError);
+ accessResultList.Add(dataAccessError);
- element = LinkedList_getNext (element);
- }
+ element = LinkedList_getNext(element);
+ }
- LinkedList_destroyStatic (accessResults);
- }
+ LinkedList_destroyStatic(accessResults);
+ }
- if (error != 0)
- throw new IedConnectionException ("Writing data set failed", error);
+ if (error != 0)
+ throw new IedConnectionException("Writing data set failed", error);
- return accessResultList;
- }
+ return accessResultList;
+ }
- ///
- /// Create a new data set.
- ///
- /// This function creates a new data set at the server. The data set consists of the members defined
- /// by the list of object references provided.
- /// The object reference of the data set
- /// A list of object references of the data set elements
- /// This exception is thrown if there is a connection or service error
- public void CreateDataSet (string dataSetReference, List dataSetElements)
- {
- IntPtr linkedList = LinkedList_create ();
+ ///
+ /// Create a new data set.
+ ///
+ /// This function creates a new data set at the server. The data set consists of the members defined
+ /// by the list of object references provided.
+ /// The object reference of the data set
+ /// A list of object references of the data set elements
+ /// This exception is thrown if there is a connection or service error
+ public void CreateDataSet(string dataSetReference, List dataSetElements)
+ {
+ IntPtr linkedList = LinkedList_create();
- foreach (string dataSetElement in dataSetElements) {
- IntPtr handle = System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi (dataSetElement);
+ foreach (string dataSetElement in dataSetElements)
+ {
+ IntPtr handle = System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(dataSetElement);
- LinkedList_add (linkedList, handle);
- }
+ LinkedList_add(linkedList, handle);
+ }
- int error;
+ int error;
- IedConnection_createDataSet (connection, out error, dataSetReference, linkedList);
+ IedConnection_createDataSet(connection, out error, dataSetReference, linkedList);
- LinkedList_destroyDeep(linkedList, new LinkedListValueDeleteFunction(FreeHGlobaleDeleteFunction));
+ LinkedList_destroyDeep(linkedList, new LinkedListValueDeleteFunction(FreeHGlobaleDeleteFunction));
- if (error != 0)
- throw new IedConnectionException ("Failed to create data set", error);
+ if (error != 0)
+ throw new IedConnectionException("Failed to create data set", error);
- }
+ }
- ///
- /// Delete a data set.
- ///
- /// This function will delete a data set at the server. This function may fail if the data set is not
- /// deletable.
- /// The object reference of the data set
- /// true if data set has been deleted, false otherwise
- /// This exception is thrown if there is a connection or service error
- public bool DeleteDataSet (string dataSetReference)
- {
- int error;
+ ///
+ /// Delete a data set.
+ ///
+ /// This function will delete a data set at the server. This function may fail if the data set is not
+ /// deletable.
+ /// The object reference of the data set
+ /// true if data set has been deleted, false otherwise
+ /// This exception is thrown if there is a connection or service error
+ public bool DeleteDataSet(string dataSetReference)
+ {
+ int error;
- bool isDeleted = IedConnection_deleteDataSet (connection, out error, dataSetReference);
+ bool isDeleted = IedConnection_deleteDataSet(connection, out error, dataSetReference);
- if (error != 0)
- throw new IedConnectionException ("Failed to delete data set", error);
+ if (error != 0)
+ throw new IedConnectionException("Failed to delete data set", error);
- return isDeleted;
- }
+ return isDeleted;
+ }
///
/// Get the directory of the data set.
@@ -1899,7 +1936,7 @@ namespace IEC61850
/// The object reference of the data set
/// the list of object references
/// This exception is thrown if there is a connection or service error
- public List GetDataSetDirectory(string dataSetReference)
+ public List GetDataSetDirectory(string dataSetReference)
{
bool isDeletable;
@@ -1913,32 +1950,33 @@ namespace IEC61850
/// The object reference of the data set
/// Indication if this data set is permanent or deletable.
/// the list of object references
- /// This exception is thrown if there is a connection or service error
- public List GetDataSetDirectory (string dataSetReference, out bool isDeletable)
- {
- int error;
+ /// This exception is thrown if there is a connection or service error
+ public List GetDataSetDirectory(string dataSetReference, out bool isDeletable)
+ {
+ int error;
- IntPtr linkedList = IedConnection_getDataSetDirectory (connection, out error, dataSetReference, out isDeletable);
+ IntPtr linkedList = IedConnection_getDataSetDirectory(connection, out error, dataSetReference, out isDeletable);
- if (error != 0)
- throw new IedConnectionException ("getDataSetDirectory failed", error);
+ if (error != 0)
+ throw new IedConnectionException("getDataSetDirectory failed", error);
- IntPtr element = LinkedList_getNext (linkedList);
+ IntPtr element = LinkedList_getNext(linkedList);
- List newList = new List ();
+ List newList = new List();
- while (element != IntPtr.Zero) {
- string dataObject = Marshal.PtrToStringAnsi (LinkedList_getData (element));
+ while (element != IntPtr.Zero)
+ {
+ string dataObject = Marshal.PtrToStringAnsi(LinkedList_getData(element));
- newList.Add (dataObject);
+ newList.Add(dataObject);
- element = LinkedList_getNext (element);
- }
+ element = LinkedList_getNext(element);
+ }
- LinkedList_destroy (linkedList);
+ LinkedList_destroy(linkedList);
- return newList;
- }
+ return newList;
+ }
///
@@ -1948,13 +1986,13 @@ namespace IEC61850
/// user provided callback parameter
/// Error code of response or timeout error in case of a response timeout
/// The read result value or null in case of an error
- public delegate void ReadValueHandler(UInt32 invokeId, object parameter, IedClientError err, MmsValue value);
+ public delegate void ReadValueHandler(UInt32 invokeId,object parameter,IedClientError err,MmsValue value);
- private void nativeReadObjectHandler (UInt32 invokeId, IntPtr parameter, int err, IntPtr value)
+ private void nativeReadObjectHandler(UInt32 invokeId, IntPtr parameter, int err, IntPtr value)
{
GCHandle handle = GCHandle.FromIntPtr(parameter);
- Tuple callbackInfo = handle.Target as Tuple;
+ Tuple callbackInfo = handle.Target as Tuple;
ReadValueHandler handler = callbackInfo.Item1;
object handlerParameter = callbackInfo.Item2;
@@ -1999,11 +2037,11 @@ namespace IEC61850
return invokeId;
}
- private void nativeGetVariableSpecifcationHandler (UInt32 invokeId, IntPtr parameter, int err, IntPtr spec)
+ private void nativeGetVariableSpecifcationHandler(UInt32 invokeId, IntPtr parameter, int err, IntPtr spec)
{
GCHandle handle = GCHandle.FromIntPtr(parameter);
- Tuple callbackInfo = handle.Target as Tuple;
+ Tuple callbackInfo = handle.Target as Tuple;
GetVariableSpecifcationHandler handler = callbackInfo.Item1;
object handlerParameter = callbackInfo.Item2;
@@ -2020,7 +2058,7 @@ namespace IEC61850
handler(invokeId, handlerParameter, clientError, varSpec);
}
- public delegate void GetVariableSpecifcationHandler(UInt32 invokeId, object parameter, IedClientError err, MmsVariableSpecification spec);
+ public delegate void GetVariableSpecifcationHandler(UInt32 invokeId,object parameter,IedClientError err,MmsVariableSpecification spec);
/// Read the variable specification (type description of a DA or FCDO
/// The object reference of a DA or FCDO.
@@ -2048,11 +2086,11 @@ namespace IEC61850
return invokeId;
}
- private void nativeReadDataSetHandler (UInt32 invokeId, IntPtr parameter, int err, IntPtr nativeDataSet)
+ private void nativeReadDataSetHandler(UInt32 invokeId, IntPtr parameter, int err, IntPtr nativeDataSet)
{
GCHandle handle = GCHandle.FromIntPtr(parameter);
- Tuple callbackInfo = handle.Target as Tuple;
+ Tuple callbackInfo = handle.Target as Tuple;
ReadDataSetHandler handler = callbackInfo.Item1;
object handlerParameter = callbackInfo.Item2;
@@ -2073,7 +2111,7 @@ namespace IEC61850
}
- public delegate void ReadDataSetHandler(UInt32 invokeId, object parameter, IedClientError err, DataSet dataSet);
+ public delegate void ReadDataSetHandler(UInt32 invokeId,object parameter,IedClientError err,DataSet dataSet);
///
/// Read the values of a data set (GetDataSetValues service) - asynchronous version
@@ -2118,13 +2156,13 @@ namespace IEC61850
/// The invoke ID of the reqeust triggering this callback
/// user provided callback parameter
/// Error code of response or timeout error in case of a response timeout
- public delegate void WriteValueHandler(UInt32 invokeId, object parameter, IedClientError err);
+ public delegate void WriteValueHandler(UInt32 invokeId,object parameter,IedClientError err);
- private void nativeWriteObjectHandler (UInt32 invokeId, IntPtr parameter, int err)
+ private void nativeWriteObjectHandler(UInt32 invokeId, IntPtr parameter, int err)
{
GCHandle handle = GCHandle.FromIntPtr(parameter);
- Tuple callbackInfo = handle.Target as Tuple;
+ Tuple callbackInfo = handle.Target as Tuple;
WriteValueHandler handler = callbackInfo.Item1;
object handlerParameter = callbackInfo.Item2;
@@ -2156,9 +2194,9 @@ namespace IEC61850
return invokeId;
}
- public delegate void GetNameListHandler(UInt32 invokeId, object parameter, IedClientError err, List nameList, bool moreFollows);
+ public delegate void GetNameListHandler(UInt32 invokeId,object parameter,IedClientError err,List nameList,bool moreFollows);
- private void nativeGetNameListHandler (UInt32 invokeId, IntPtr parameter, int err, IntPtr nameList, [MarshalAs(UnmanagedType.I1)] bool moreFollows)
+ private void nativeGetNameListHandler(UInt32 invokeId, IntPtr parameter, int err, IntPtr nameList, [MarshalAs(UnmanagedType.I1)] bool moreFollows)
{
GCHandle handle = GCHandle.FromIntPtr(parameter);
@@ -2198,7 +2236,7 @@ namespace IEC61850
}
}
-
+
///
/// Gets the server directory (Logical devices or file objects)
///
@@ -2276,14 +2314,14 @@ namespace IEC61850
return invokeId;
}
- public delegate void QueryLogHandler(UInt32 invokeId, object parameter, IedClientError err, List journalEntries, bool moreFollows);
+ public delegate void QueryLogHandler(UInt32 invokeId,object parameter,IedClientError err,List journalEntries,bool moreFollows);
- private void nativeQueryLogHandler (UInt32 invokeId, IntPtr parameter, int err, IntPtr journalEntries,
- [MarshalAs(UnmanagedType.I1)] bool moreFollows)
+ private void nativeQueryLogHandler(UInt32 invokeId, IntPtr parameter, int err, IntPtr journalEntries,
+ [MarshalAs(UnmanagedType.I1)] bool moreFollows)
{
GCHandle handle = GCHandle.FromIntPtr(parameter);
- Tuple callbackInfo = handle.Target as Tuple;
+ Tuple callbackInfo = handle.Target as Tuple;
QueryLogHandler handler = callbackInfo.Item1;
object handlerParameter = callbackInfo.Item2;
@@ -2338,10 +2376,10 @@ namespace IEC61850
/// This exception is thrown if there is a connection or service error
public UInt32 QueryLogByTimeAsync(string logRef, DateTime startTime, DateTime stopTime, QueryLogHandler handler, object parameter)
{
- ulong startTimeMs = LibIEC61850.DateTimeToMsTimestamp (startTime);
- ulong stopTimeMs = LibIEC61850.DateTimeToMsTimestamp (stopTime);
+ ulong startTimeMs = LibIEC61850.DateTimeToMsTimestamp(startTime);
+ ulong stopTimeMs = LibIEC61850.DateTimeToMsTimestamp(stopTime);
- return QueryLogByTimeAsync (logRef, startTimeMs, stopTimeMs, handler, parameter);
+ return QueryLogByTimeAsync(logRef, startTimeMs, stopTimeMs, handler, parameter);
}
///
@@ -2361,9 +2399,9 @@ namespace IEC61850
GCHandle handle = GCHandle.Alloc(callbackInfo);
- MmsValue entryIdValue = new MmsValue (entryID);
+ MmsValue entryIdValue = new MmsValue(entryID);
- UInt32 invokeId = IedConnection_queryLogAfterAsync(connection, out error, logRef, entryIdValue.valueReference, timestamp, nativeQueryLogHandler, GCHandle.ToIntPtr(handle));
+ UInt32 invokeId = IedConnection_queryLogAfterAsync(connection, out error, logRef, entryIdValue.valueReference, timestamp, nativeQueryLogHandler, GCHandle.ToIntPtr(handle));
if (error != 0)
{
@@ -2374,40 +2412,48 @@ namespace IEC61850
return invokeId;
}
- internal void UninstallReportHandler (string objectReference)
- {
- if (connection != IntPtr.Zero) {
- IedConnection_uninstallReportHandler (connection, objectReference);
- }
- }
-
- internal void InstallReportHandler (string objectReference, string reportId, InternalReportHandler internalHandler)
- {
- if (connection != IntPtr.Zero) {
- IedConnection_installReportHandler (connection, objectReference, reportId, internalHandler, IntPtr.Zero);
- }
- }
-
- internal void GetRCBValues(out int error, string objectReference, IntPtr updateRcb)
- {
- if (connection != IntPtr.Zero) {
- IedConnection_getRCBValues (connection, out error, objectReference, updateRcb);
- } else {
- error = 1; /* not connected */
- }
- }
-
- internal void SetRCBValues(out int error, IntPtr rcb, UInt32 parametersMask, bool singleRequest)
- {
- if (connection != IntPtr.Zero) {
- IedConnection_setRCBValues (connection, out error, rcb, parametersMask, singleRequest);
- } else {
- error = 1; /* not connected */
- }
- }
-
+ internal void UninstallReportHandler(string objectReference)
+ {
+ if (connection != IntPtr.Zero)
+ {
+ IedConnection_uninstallReportHandler(connection, objectReference);
+ }
+ }
+
+ internal void InstallReportHandler(string objectReference, string reportId, InternalReportHandler internalHandler)
+ {
+ if (connection != IntPtr.Zero)
+ {
+ IedConnection_installReportHandler(connection, objectReference, reportId, internalHandler, IntPtr.Zero);
+ }
+ }
+
+ internal void GetRCBValues(out int error, string objectReference, IntPtr updateRcb)
+ {
+ if (connection != IntPtr.Zero)
+ {
+ IedConnection_getRCBValues(connection, out error, objectReference, updateRcb);
+ }
+ else
+ {
+ error = 1; /* not connected */
+ }
+ }
+
+ internal void SetRCBValues(out int error, IntPtr rcb, UInt32 parametersMask, bool singleRequest)
+ {
+ if (connection != IntPtr.Zero)
+ {
+ IedConnection_setRCBValues(connection, out error, rcb, parametersMask, singleRequest);
+ }
+ else
+ {
+ error = 1; /* not connected */
+ }
+ }
+
- private void nativeGetRCBValuesHandler (UInt32 invokeId, IntPtr parameter, int err, IntPtr rcbPtr)
+ private void nativeGetRCBValuesHandler(UInt32 invokeId, IntPtr parameter, int err, IntPtr rcbPtr)
{
GCHandle handle = GCHandle.FromIntPtr(parameter);
@@ -2443,7 +2489,7 @@ namespace IEC61850
return invokeId;
}
- private void nativeSetRcbValuesHandler (UInt32 invokeId, IntPtr parameter, int err)
+ private void nativeSetRcbValuesHandler(UInt32 invokeId, IntPtr parameter, int err)
{
GCHandle handle = GCHandle.FromIntPtr(parameter);
@@ -2479,35 +2525,37 @@ namespace IEC61850
return invokeId;
}
- }
+ }
- public class IedConnectionException : Exception
- {
+ public class IedConnectionException : Exception
+ {
- private int errorCode;
+ private int errorCode;
- public IedConnectionException (string message, int errorCode) : base(message)
- {
- this.errorCode = errorCode;
- }
+ public IedConnectionException(string message, int errorCode)
+ : base(message)
+ {
+ this.errorCode = errorCode;
+ }
- public IedConnectionException (string message) : base(message)
- {
- this.errorCode = 0;
- }
+ public IedConnectionException(string message)
+ : base(message)
+ {
+ this.errorCode = 0;
+ }
- public int GetErrorCode ()
- {
- return this.errorCode;
- }
+ public int GetErrorCode()
+ {
+ return this.errorCode;
+ }
- public IedClientError GetIedClientError ()
- {
- return (IedClientError)this.errorCode;
- }
- }
+ public IedClientError GetIedClientError()
+ {
+ return (IedClientError)this.errorCode;
+ }
+ }
- public class FileDirectoryEntry
+ public class FileDirectoryEntry
{
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr FileDirectoryEntry_getFileName(IntPtr self);
@@ -2522,24 +2570,24 @@ namespace IEC61850
private UInt32 fileSize;
private UInt64 lastModified;
- internal FileDirectoryEntry(IntPtr nativeFileDirectoryEntry)
+ internal FileDirectoryEntry(IntPtr nativeFileDirectoryEntry)
{
fileName = Marshal.PtrToStringAnsi(FileDirectoryEntry_getFileName(nativeFileDirectoryEntry));
fileSize = FileDirectoryEntry_getFileSize(nativeFileDirectoryEntry);
lastModified = FileDirectoryEntry_getLastModified(nativeFileDirectoryEntry);
}
- public string GetFileName()
+ public string GetFileName()
{
return fileName;
}
- public UInt32 GetFileSize()
+ public UInt32 GetFileSize()
{
return fileSize;
}
- public UInt64 GetLastModified()
+ public UInt64 GetLastModified()
{
return lastModified;
}
@@ -2574,60 +2622,60 @@ namespace IEC61850
///
/// Error codes for client side functions
///
- public enum IedClientError
- {
- /* general errors */
+ public enum IedClientError
+ {
+ /* general errors */
- /** No error occurred - service request has been successful */
- IED_ERROR_OK = 0,
+ /** No error occurred - service request has been successful */
+ IED_ERROR_OK = 0,
- /** The service request can not be executed because the client is not yet connected */
- IED_ERROR_NOT_CONNECTED = 1,
+ /** The service request can not be executed because the client is not yet connected */
+ IED_ERROR_NOT_CONNECTED = 1,
- /** Connect service not execute because the client is already connected */
- IED_ERROR_ALREADY_CONNECTED = 2,
+ /** Connect service not execute because the client is already connected */
+ IED_ERROR_ALREADY_CONNECTED = 2,
- /** The service request can not be executed caused by a loss of connection */
- IED_ERROR_CONNECTION_LOST = 3,
+ /** The service request can not be executed caused by a loss of connection */
+ IED_ERROR_CONNECTION_LOST = 3,
- /** The service or some given parameters are not supported by the client stack or by the server */
- IED_ERROR_SERVICE_NOT_SUPPORTED = 4,
+ /** The service or some given parameters are not supported by the client stack or by the server */
+ IED_ERROR_SERVICE_NOT_SUPPORTED = 4,
- /** Connection rejected by server */
- IED_ERROR_CONNECTION_REJECTED = 5,
+ /** Connection rejected by server */
+ IED_ERROR_CONNECTION_REJECTED = 5,
- /* client side errors */
+ /* client side errors */
- /** API function has been called with an invalid argument */
- IED_ERROR_USER_PROVIDED_INVALID_ARGUMENT = 10,
+ /** API function has been called with an invalid argument */
+ IED_ERROR_USER_PROVIDED_INVALID_ARGUMENT = 10,
- IED_ERROR_ENABLE_REPORT_FAILED_DATASET_MISMATCH = 11,
+ IED_ERROR_ENABLE_REPORT_FAILED_DATASET_MISMATCH = 11,
- /** The object provided object reference is invalid (there is a syntactical error). */
- IED_ERROR_OBJECT_REFERENCE_INVALID = 12,
+ /** The object provided object reference is invalid (there is a syntactical error). */
+ IED_ERROR_OBJECT_REFERENCE_INVALID = 12,
- /** Received object is of unexpected type */
- IED_ERROR_UNEXPECTED_VALUE_RECEIVED = 13,
+ /** Received object is of unexpected type */
+ IED_ERROR_UNEXPECTED_VALUE_RECEIVED = 13,
- /* service error - error reported by server */
+ /* service error - error reported by server */
- /** The communication to the server failed with a timeout */
- IED_ERROR_TIMEOUT = 20,
+ /** The communication to the server failed with a timeout */
+ IED_ERROR_TIMEOUT = 20,
- /** The server rejected the access to the requested object/service due to access control */
- IED_ERROR_ACCESS_DENIED = 21,
+ /** The server rejected the access to the requested object/service due to access control */
+ IED_ERROR_ACCESS_DENIED = 21,
- /** The server reported that the requested object does not exist */
- IED_ERROR_OBJECT_DOES_NOT_EXIST = 22,
+ /** The server reported that the requested object does not exist */
+ IED_ERROR_OBJECT_DOES_NOT_EXIST = 22,
- /** The server reported that the requested object already exists */
- IED_ERROR_OBJECT_EXISTS = 23,
+ /** The server reported that the requested object already exists */
+ IED_ERROR_OBJECT_EXISTS = 23,
- /** The server does not support the requested access method */
- IED_ERROR_OBJECT_ACCESS_UNSUPPORTED = 24,
+ /** The server does not support the requested access method */
+ IED_ERROR_OBJECT_ACCESS_UNSUPPORTED = 24,
- /** The server expected an object of another type */
- IED_ERROR_TYPE_INCONSISTENT = 25,
+ /** The server expected an object of another type */
+ IED_ERROR_TYPE_INCONSISTENT = 25,
/** The object or service is temporarily unavailable */
IED_ERROR_TEMPORARILY_UNAVAILABLE = 26,
@@ -2653,8 +2701,14 @@ namespace IEC61850
/** The object is invalidated (returned by server) */
IED_ERROR_OBJECT_INVALIDATED = 33,
- /* unknown error */
- IED_ERROR_UNKNOWN = 99
- }
- }
+ /** Received an invalid response message from the server */
+ IED_ERROR_MALFORMED_MESSAGE = 34,
+
+ /** Service not implemented */
+ IED_ERROR_SERVICE_NOT_IMPLEMENTED = 98,
+
+ /* unknown error */
+ IED_ERROR_UNKNOWN = 99
+ }
+ }
}
diff --git a/src/iec61850/client/client_report.c b/src/iec61850/client/client_report.c
index 26c670c4..41683a41 100644
--- a/src/iec61850/client/client_report.c
+++ b/src/iec61850/client/client_report.c
@@ -3,7 +3,7 @@
*
* Client implementation for IEC 61850 reporting.
*
- * Copyright 2013-2018 Michael Zillgith
+ * Copyright 2013-2019 Michael Zillgith
*
* This file is part of libIEC61850.
*
@@ -43,6 +43,8 @@ struct sClientReport
char* dataSetName;
int dataSetNameSize; /* size of the dataSetName buffer */
+ int dataSetSize;
+
MmsValue* entryId;
MmsValue* dataReferences;
MmsValue* dataSetValues;
@@ -93,6 +95,8 @@ ClientReport_create()
{
ClientReport self = (ClientReport) GLOBAL_CALLOC(1, sizeof(struct sClientReport));
+ self->dataSetSize = -1;
+
return self;
}
@@ -607,6 +611,18 @@ iedConnection_handleReport(IedConnection self, MmsValue* value)
int dataSetSize = MmsValue_getBitStringSize(inclusion);
+ if (matchingReport->dataSetSize == -1) {
+ matchingReport->dataSetSize = dataSetSize;
+ }
+ else {
+ if (dataSetSize != matchingReport->dataSetSize) {
+ if (DEBUG_IED_CLIENT)
+ printf("IED_CLIENT: received malformed report (inclusion has no plausible size)\n");
+
+ goto exit_function;
+ }
+ }
+
int includedElements = MmsValue_getNumberOfSetBits(inclusion);
if (DEBUG_IED_CLIENT)
@@ -692,7 +708,7 @@ iedConnection_handleReport(IedConnection self, MmsValue* value)
MmsValue_update(dataSetElement, newElementValue);
if (DEBUG_IED_CLIENT)
- printf("IED_CLIENT: update element value type: %i\n", MmsValue_getType(newElementValue));
+ printf("IED_CLIENT: update element value type: %i\n", MmsValue_getType(newElementValue));
valueIndex++;
diff --git a/src/iec61850/client/ied_connection.c b/src/iec61850/client/ied_connection.c
index 9299b42a..8b30c753 100644
--- a/src/iec61850/client/ied_connection.c
+++ b/src/iec61850/client/ied_connection.c
@@ -1,7 +1,7 @@
/*
* ied_connection.c
*
- * Copyright 2013-2018 Michael Zillgith
+ * Copyright 2013-2019 Michael Zillgith
*
* This file is part of libIEC61850.
*
@@ -96,6 +96,9 @@ iedConnection_mapMmsErrorToIedError(MmsError mmsError)
case MMS_ERROR_ACCESS_OBJECT_VALUE_INVALID:
return IED_ERROR_OBJECT_VALUE_INVALID;
+ case MMS_ERROR_PARSING_RESPONSE:
+ return IED_ERROR_MALFORMED_MESSAGE;
+
default:
return IED_ERROR_UNKNOWN;
}
@@ -484,42 +487,48 @@ informationReportHandler(void* parameter, char* domainName,
{
IedConnection self = (IedConnection) parameter;
- if (DEBUG_IED_CLIENT)
- printf("DEBUG_IED_CLIENT: received information report for %s\n", variableListName);
+ if (value) {
+ if (DEBUG_IED_CLIENT)
+ printf("IED_CLIENT: received information report for %s\n", variableListName);
- if (domainName == NULL) {
+ if (domainName == NULL) {
- if (isVariableListName) {
- iedConnection_handleReport(self, value);
- }
- else {
- if (strcmp(variableListName, "LastApplError") == 0)
- handleLastApplErrorMessage(self, value);
+ if (isVariableListName) {
+ iedConnection_handleReport(self, value);
+ }
else {
- if (DEBUG_IED_CLIENT)
- printf("IED_CLIENT: Received unknown variable list report for list: %s\n", variableListName);
+ if (strcmp(variableListName, "LastApplError") == 0)
+ handleLastApplErrorMessage(self, value);
+ else {
+ if (DEBUG_IED_CLIENT)
+ printf("IED_CLIENT: Received unknown variable list report for list: %s\n", variableListName);
+ }
}
}
- }
- else {
- if (DEBUG_IED_CLIENT)
- printf("IED_CLIENT: RCVD CommandTermination for %s/%s\n", domainName, variableListName);
+ else {
+ if (DEBUG_IED_CLIENT)
+ printf("IED_CLIENT: RCVD CommandTermination for %s/%s\n", domainName, variableListName);
- LinkedList control = LinkedList_getNext(self->clientControls);
+ LinkedList control = LinkedList_getNext(self->clientControls);
- while (control != NULL) {
- ControlObjectClient object = (ControlObjectClient) control->data;
+ while (control != NULL) {
+ ControlObjectClient object = (ControlObjectClient) control->data;
- const char* objectRef = ControlObjectClient_getObjectReference(object);
+ const char* objectRef = ControlObjectClient_getObjectReference(object);
- if (doesReportMatchControlObject(domainName, variableListName, objectRef))
- controlObjectClient_invokeCommandTerminationHandler(object);
+ if (doesReportMatchControlObject(domainName, variableListName, objectRef))
+ controlObjectClient_invokeCommandTerminationHandler(object);
- control = LinkedList_getNext(control);
+ control = LinkedList_getNext(control);
+ }
}
- }
- MmsValue_delete(value);
+ MmsValue_delete(value);
+ }
+ else {
+ if (DEBUG_IED_CLIENT)
+ printf("IED_CLIENT: report for %s/%s: value invalid\n", domainName, variableListName);
+ }
}
static void
diff --git a/src/iec61850/inc/iec61850_client.h b/src/iec61850/inc/iec61850_client.h
index 2a673439..de29ff9c 100644
--- a/src/iec61850/inc/iec61850_client.h
+++ b/src/iec61850/inc/iec61850_client.h
@@ -1,7 +1,7 @@
/*
* iec61850_client.h
*
- * Copyright 2013-2018 Michael Zillgith
+ * Copyright 2013-2019 Michael Zillgith
*
* This file is part of libIEC61850.
*
@@ -159,6 +159,9 @@ typedef enum {
/** The object is invalidated (returned by server) */
IED_ERROR_OBJECT_INVALIDATED = 33,
+ /** Received an invalid response message from the server */
+ IED_ERROR_MALFORMED_MESSAGE = 34,
+
/** Service not implemented */
IED_ERROR_SERVICE_NOT_IMPLEMENTED = 98,
diff --git a/src/iec61850/server/mms_mapping/control.c b/src/iec61850/server/mms_mapping/control.c
index ec2f3383..9a4548ea 100644
--- a/src/iec61850/server/mms_mapping/control.c
+++ b/src/iec61850/server/mms_mapping/control.c
@@ -1,7 +1,7 @@
/*
* control.c
*
- * Copyright 2013-2018 Michael Zillgith
+ * Copyright 2013-2019 Michael Zillgith
*
* This file is part of libIEC61850.
*
@@ -316,10 +316,25 @@ ControlObject_create(IedServer iedServer, MmsDomain* domain, char* lnName, char*
self->iedServer = iedServer;
MmsVariableSpecification* ctlValSpec = MmsVariableSpecification_getChildSpecificationByName(operSpec, "ctlVal", NULL);
- self->ctlVal = MmsValue_newDefaultValue(ctlValSpec);
+
+ if (ctlValSpec) {
+ self->ctlVal = MmsValue_newDefaultValue(ctlValSpec);
+ }
+ else {
+ if (DEBUG_IED_SERVER)
+ printf("IED_SERVER: control object %s/%s.%s has no ctlVal element!\n", domain->domainName, lnName, name);
+ }
+
MmsVariableSpecification* originSpec = MmsVariableSpecification_getChildSpecificationByName(operSpec, "origin", NULL);
- self->origin = MmsValue_newDefaultValue(originSpec);
+
+ if (originSpec) {
+ self->origin = MmsValue_newDefaultValue(originSpec);
+ }
+ else {
+ if (DEBUG_IED_SERVER)
+ printf("IED_SERVER: control object %s/%s.%s has no origin element!\n", domain->domainName, lnName, name);
+ }
self->ctlNum = MmsValue_newUnsigned(8);
diff --git a/src/mms/iso_mms/client/mms_client_connection.c b/src/mms/iso_mms/client/mms_client_connection.c
index f27a55a1..7f4bac36 100644
--- a/src/mms/iso_mms/client/mms_client_connection.c
+++ b/src/mms/iso_mms/client/mms_client_connection.c
@@ -1,7 +1,7 @@
/*
* mms_client_connection.c
*
- * Copyright 2013-2018 Michael Zillgith
+ * Copyright 2013-2019 Michael Zillgith
*
* This file is part of libIEC61850.
*
@@ -657,7 +657,10 @@ handleAsyncResponse(MmsConnection self, ByteBuffer* response, uint32_t bufPos, M
if (response) {
MmsValue* value = mmsClient_parseReadResponse(response, NULL, false);
- handler(outstandingCall->invokeId, outstandingCall->userParameter, MMS_ERROR_NONE, value);
+ if (value == NULL)
+ err = MMS_ERROR_PARSING_RESPONSE;
+
+ handler(outstandingCall->invokeId, outstandingCall->userParameter, err, value);
}
}
@@ -673,7 +676,10 @@ handleAsyncResponse(MmsConnection self, ByteBuffer* response, uint32_t bufPos, M
if (response) {
MmsValue* value = mmsClient_parseReadResponse(response, NULL, true);
- handler(outstandingCall->invokeId, outstandingCall->userParameter, MMS_ERROR_NONE, value);
+ if (value == NULL)
+ err = MMS_ERROR_PARSING_RESPONSE;
+
+ handler(outstandingCall->invokeId, outstandingCall->userParameter, err, value);
}
}
@@ -726,7 +732,7 @@ handleAsyncResponse(MmsConnection self, ByteBuffer* response, uint32_t bufPos, M
LinkedList accessSpec = mmsClient_parseGetNamedVariableListAttributesResponse(response, &deletable);
- if (accessSpec == false)
+ if (accessSpec == NULL)
err = MMS_ERROR_PARSING_RESPONSE;
handler(outstandingCall->invokeId, outstandingCall->userParameter, err, accessSpec, deletable);
@@ -779,6 +785,9 @@ handleAsyncResponse(MmsConnection self, ByteBuffer* response, uint32_t bufPos, M
else {
MmsVariableSpecification* typeSpec = mmsClient_parseGetVariableAccessAttributesResponse(response, NULL);
+ if (typeSpec == NULL)
+ err = MMS_ERROR_PARSING_RESPONSE;
+
handler(outstandingCall->invokeId, outstandingCall->userParameter, err, typeSpec);
}
}
diff --git a/src/mms/iso_mms/client/mms_client_get_var_access.c b/src/mms/iso_mms/client/mms_client_get_var_access.c
index 68d6449d..8c0951e5 100644
--- a/src/mms/iso_mms/client/mms_client_get_var_access.c
+++ b/src/mms/iso_mms/client/mms_client_get_var_access.c
@@ -138,24 +138,25 @@ mmsClient_parseGetVariableAccessAttributesResponse(ByteBuffer* message, uint32_t
asn_dec_rval_t rval = ber_decode(NULL, &asn_DEF_MmsPdu,
(void**) &mmsPdu, ByteBuffer_getBuffer(message), ByteBuffer_getSize(message));
- if (rval.code != RC_OK)
- return NULL;
+ if (rval.code == RC_OK) {
- if (mmsPdu->present == MmsPdu_PR_confirmedResponsePdu) {
+ if (mmsPdu->present == MmsPdu_PR_confirmedResponsePdu) {
- if (invokeId != NULL)
- *invokeId = mmsClient_getInvokeId(&mmsPdu->choice.confirmedResponsePdu);
+ if (invokeId != NULL)
+ *invokeId = mmsClient_getInvokeId(&mmsPdu->choice.confirmedResponsePdu);
- if (mmsPdu->choice.confirmedResponsePdu.confirmedServiceResponse.present ==
- ConfirmedServiceResponse_PR_getVariableAccessAttributes)
- {
- GetVariableAccessAttributesResponse_t* response;
+ if (mmsPdu->choice.confirmedResponsePdu.confirmedServiceResponse.present ==
+ ConfirmedServiceResponse_PR_getVariableAccessAttributes)
+ {
+ GetVariableAccessAttributesResponse_t* response;
- response = &(mmsPdu->choice.confirmedResponsePdu.confirmedServiceResponse.choice.getVariableAccessAttributes);
- TypeSpecification_t* asnTypeSpec = &response->typeSpecification;
+ response = &(mmsPdu->choice.confirmedResponsePdu.confirmedServiceResponse.choice.getVariableAccessAttributes);
+ TypeSpecification_t* asnTypeSpec = &response->typeSpecification;
- typeSpec = createTypeSpecification(asnTypeSpec);
+ typeSpec = createTypeSpecification(asnTypeSpec);
+ }
}
+
}
asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0);
diff --git a/src/mms/iso_mms/client/mms_client_read.c b/src/mms/iso_mms/client/mms_client_read.c
index 4bc82e9e..ceef5885 100644
--- a/src/mms/iso_mms/client/mms_client_read.c
+++ b/src/mms/iso_mms/client/mms_client_read.c
@@ -1,7 +1,7 @@
/*
* mms_client_read.c
*
- * Copyright 2013-2018 Michael Zillgith
+ * Copyright 2013-2019 Michael Zillgith
*
* This file is part of libIEC61850.
*
@@ -46,11 +46,14 @@ mmsClient_parseListOfAccessResults(AccessResult_t** accessResultList, int listSi
int i = 0;
for (i = 0; i < elementCount; i++) {
+
+ value = NULL;
+
AccessResult_PR presentType = accessResultList[i]->present;
if (presentType == AccessResult_PR_failure) {
if (DEBUG_MMS_CLIENT)
- printf("access error!\n");
+ printf("MMS CLIENT: received access error!\n");
if (accessResultList[i]->choice.failure.size > 0) {
int errorCode = (int) accessResultList[i]->choice.failure.buf[0];
@@ -66,72 +69,138 @@ mmsClient_parseListOfAccessResults(AccessResult_t** accessResultList, int listSi
value = MmsValue_newDataAccessError(DATA_ACCESS_ERROR_UNKNOWN);
}
else if (presentType == AccessResult_PR_array) {
- value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
- value->type = MMS_ARRAY;
int arrayElementCount =
accessResultList[i]->choice.array.list.count;
- value->value.structure.size = arrayElementCount;
- value->value.structure.components = (MmsValue**) GLOBAL_CALLOC(arrayElementCount, sizeof(MmsValue*));
-
- int j;
-
- for (j = 0; j < arrayElementCount; j++) {
- value->value.structure.components[j] = mmsMsg_parseDataElement(
- accessResultList[i]->choice.array.list.array[j]);
+ if (arrayElementCount > 0) {
+ value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
+ value->type = MMS_ARRAY;
+ value->value.structure.size = arrayElementCount;
+ value->value.structure.components = (MmsValue**) GLOBAL_CALLOC(arrayElementCount, sizeof(MmsValue*));
+
+ int j;
+
+ for (j = 0; j < arrayElementCount; j++) {
+ value->value.structure.components[j] = mmsMsg_parseDataElement(
+ accessResultList[i]->choice.array.list.array[j]);
+
+ if (value->value.structure.components[j] == NULL) {
+ MmsValue_delete(value);
+ value = NULL;
+ break;
+ }
+ }
+ }
+ else {
+ if (DEBUG_MMS_CLIENT)
+ printf("MMS CLIENT: error parsing access result (invalid array size)!\n");
}
+
}
else if (presentType == AccessResult_PR_structure) {
- value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
- value->type = MMS_STRUCTURE;
int componentCount =
accessResultList[i]->choice.structure.list.count;
- value->value.structure.size = componentCount;
- value->value.structure.components = (MmsValue**) GLOBAL_CALLOC(componentCount, sizeof(MmsValue*));
-
- int j;
- for (j = 0; j < componentCount; j++) {
- value->value.structure.components[j] = mmsMsg_parseDataElement(
- accessResultList[i]->choice.structure.list.array[j]);
+ if (componentCount > 0) {
+ value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
+ value->type = MMS_STRUCTURE;
+ value->value.structure.size = componentCount;
+ value->value.structure.components = (MmsValue**) GLOBAL_CALLOC(componentCount, sizeof(MmsValue*));
+
+ int j;
+ for (j = 0; j < componentCount; j++) {
+ value->value.structure.components[j] = mmsMsg_parseDataElement(
+ accessResultList[i]->choice.structure.list.array[j]);
+
+ if (value->value.structure.components[j] == NULL) {
+ MmsValue_delete(value);
+ value = NULL;
+ break;
+ }
+ }
+ }
+ else {
+ if (DEBUG_MMS_CLIENT)
+ printf("MMS CLIENT: error parsing access result (invalid structure size)!\n");
}
+
}
else if (presentType == AccessResult_PR_bitstring) {
- value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
- value->type = MMS_BIT_STRING;
+
int size = accessResultList[i]->choice.bitstring.size;
- value->value.bitString.size = (size * 8)
- - accessResultList[i]->choice.bitstring.bits_unused;
+ if (size > 0) {
+
+ int maxSize = (size * 8);
+ int bitSize = maxSize - accessResultList[i]->choice.bitstring.bits_unused;
+
+ if ((bitSize > 0) && (maxSize >= bitSize)) {
+
+ value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
+ value->type = MMS_BIT_STRING;
- value->value.bitString.buf = (uint8_t*) GLOBAL_MALLOC(size);
- memcpy(value->value.bitString.buf,
- accessResultList[i]->choice.bitstring.buf, size);
+
+ value->value.bitString.size = (size * 8)
+ - accessResultList[i]->choice.bitstring.bits_unused;
+
+ value->value.bitString.buf = (uint8_t*) GLOBAL_MALLOC(size);
+ memcpy(value->value.bitString.buf,
+ accessResultList[i]->choice.bitstring.buf, size);
+ }
+ else {
+ if (DEBUG_MMS_CLIENT)
+ printf("MMS CLIENT: error parsing access result (bit string padding problem)!\n");
+ }
+ }
+ else {
+ if (DEBUG_MMS_CLIENT)
+ printf("MMS CLIENT: error parsing access result (bit string size 0 or negative)!\n");
+ }
}
else if (presentType == AccessResult_PR_integer) {
- Asn1PrimitiveValue* berInteger =
- BerInteger_createFromBuffer(accessResultList[i]->choice.integer.buf,
- accessResultList[i]->choice.integer.size);
- value = MmsValue_newIntegerFromBerInteger(berInteger);
+ int size = accessResultList[i]->choice.integer.size;
+
+ if (size > 0) {
+ Asn1PrimitiveValue* berInteger =
+ BerInteger_createFromBuffer(accessResultList[i]->choice.integer.buf, size);
+
+ value = MmsValue_newIntegerFromBerInteger(berInteger);
+ }
+ else {
+ if (DEBUG_MMS_CLIENT)
+ printf("MMS CLIENT: error parsing access result (invalid integer size)!\n");
+ }
}
else if (presentType == AccessResult_PR_unsigned) {
- Asn1PrimitiveValue* berInteger =
- BerInteger_createFromBuffer(accessResultList[i]->choice.Unsigned.buf,
- accessResultList[i]->choice.Unsigned.size);
- value = MmsValue_newUnsignedFromBerInteger(berInteger);
+ int size = accessResultList[i]->choice.Unsigned.size;
+
+ if (size > 0) {
+ Asn1PrimitiveValue* berInteger =
+ BerInteger_createFromBuffer(accessResultList[i]->choice.Unsigned.buf,
+ accessResultList[i]->choice.Unsigned.size);
+
+ value = MmsValue_newUnsignedFromBerInteger(berInteger);
+ }
+ else {
+ if (DEBUG_MMS_CLIENT)
+ printf("MMS CLIENT: error parsing access result (invalid unsigned size)!\n");
+ }
+
}
else if (presentType == AccessResult_PR_floatingpoint) {
- int size = accessResultList[i]->choice.floatingpoint.size;
- value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
- value->type = MMS_FLOAT;
+ int size = accessResultList[i]->choice.floatingpoint.size;
if (size == 5) { /* FLOAT32 */
+
+ value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
+ value->type = MMS_FLOAT;
+
value->value.floatingPoint.formatWidth = 32;
value->value.floatingPoint.exponentWidth = accessResultList[i]->choice.floatingpoint.buf[0];
@@ -146,8 +215,11 @@ mmsClient_parseListOfAccessResults(AccessResult_t** accessResultList, int listSi
#endif
}
+ else if (size == 9) { /* FLOAT64 */
+
+ value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
+ value->type = MMS_FLOAT;
- if (size == 9) { /* FLOAT64 */
value->value.floatingPoint.formatWidth = 64;
value->value.floatingPoint.exponentWidth = accessResultList[i]->choice.floatingpoint.buf[0];
@@ -161,46 +233,70 @@ mmsClient_parseListOfAccessResults(AccessResult_t** accessResultList, int listSi
memcpy(value->value.floatingPoint.buf, floatBuf, 8);
#endif
}
+ else {
+ if (DEBUG_MMS_CLIENT)
+ printf("MMS CLIENT: error parsing float (size must be 5 or 9, is %i)\n", size);
+ }
}
else if (presentType == AccessResult_PR_visiblestring) {
- value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
-
- value->type = MMS_VISIBLE_STRING;
int strSize = accessResultList[i]->choice.visiblestring.size;
- value->value.visibleString.buf = (char*) GLOBAL_MALLOC(strSize + 1);
- value->value.visibleString.size = strSize;
+ if (strSize >= 0) {
+ value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
+
+ value->type = MMS_VISIBLE_STRING;
+ value->value.visibleString.buf = (char*) GLOBAL_MALLOC(strSize + 1);
+ value->value.visibleString.size = strSize;
- memcpy(value->value.visibleString.buf,
- accessResultList[i]->choice.visiblestring.buf,
- strSize);
+ memcpy(value->value.visibleString.buf,
+ accessResultList[i]->choice.visiblestring.buf,
+ strSize);
+
+ value->value.visibleString.buf[strSize] = 0;
+ }
+ else {
+ if (DEBUG_MMS_CLIENT)
+ printf("MMS CLIENT: error parsing access result (invalid visible-string size)\n");
+ }
- value->value.visibleString.buf[strSize] = 0;
}
else if (presentType == AccessResult_PR_mMSString) {
- value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
-
- value->type = MMS_STRING;
int strSize = accessResultList[i]->choice.mMSString.size;
- value->value.visibleString.buf = (char*) GLOBAL_MALLOC(strSize + 1);
- value->value.visibleString.size = strSize;
+ if (strSize >= 0) {
+ value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
- memcpy(value->value.visibleString.buf,
- accessResultList[i]->choice.mMSString.buf, strSize);
+ value->type = MMS_STRING;
+ value->value.visibleString.buf = (char*) GLOBAL_MALLOC(strSize + 1);
+ value->value.visibleString.size = strSize;
- value->value.visibleString.buf[strSize] = 0;
+ memcpy(value->value.visibleString.buf,
+ accessResultList[i]->choice.mMSString.buf, strSize);
+ value->value.visibleString.buf[strSize] = 0;
+ }
+ else {
+ if (DEBUG_MMS_CLIENT)
+ printf("MMS CLIENT: error parsing access result (invalid mms-string size)\n");
+ }
}
else if (presentType == AccessResult_PR_utctime) {
- value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
- value->type = MMS_UTC_TIME;
- memcpy(value->value.utcTime,
- accessResultList[i]->choice.utctime.buf, 8);
+ int size = accessResultList[i]->choice.utctime.size;
+
+ if (size == 8) {
+ value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
+
+ value->type = MMS_UTC_TIME;
+ memcpy(value->value.utcTime, accessResultList[i]->choice.utctime.buf, 8);
+ }
+ else {
+ if (DEBUG_MMS_CLIENT)
+ printf("MMS CLIENT: error parsing UTC time (size is %i instead of 8\n", size);
+ }
}
else if (presentType == AccessResult_PR_boolean) {
value = MmsValue_newBoolean(accessResultList[i]->choice.boolean);
@@ -208,25 +304,36 @@ mmsClient_parseListOfAccessResults(AccessResult_t** accessResultList, int listSi
else if (presentType == AccessResult_PR_binarytime) {
int size = accessResultList[i]->choice.binarytime.size;
- if (size <= 6) {
+ if ((size == 4) || (size == 6)) {
value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
value->type = MMS_BINARY_TIME;
value->value.binaryTime.size = size;
memcpy(value->value.binaryTime.buf, accessResultList[i]->choice.binarytime.buf, size);
}
+ else {
+ if (DEBUG_MMS_CLIENT)
+ printf("MMS CLIENT: error parsing binary time (size must be 4 or 6, is %i\n", size);
+ }
}
else if (presentType == AccessResult_PR_octetstring) {
int size = accessResultList[i]->choice.octetstring.size;
- value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
- value->type = MMS_OCTET_STRING;
- value->value.octetString.maxSize = size;
- value->value.octetString.size = size;
- value->value.octetString.buf = (uint8_t*) GLOBAL_MALLOC(size);
- memcpy(value->value.octetString.buf, accessResultList[i]->choice.octetstring.buf, size);
+ if (size >= 0) {
+ value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
+ value->type = MMS_OCTET_STRING;
+ value->value.octetString.maxSize = size;
+ value->value.octetString.size = size;
+ value->value.octetString.buf = (uint8_t*) GLOBAL_MALLOC(size);
+ memcpy(value->value.octetString.buf, accessResultList[i]->choice.octetstring.buf, size);
+ }
+ else {
+ if (DEBUG_MMS_CLIENT)
+ printf("MMS CLIENT: error parsing access result (invalid octet-string size)\n");
+ }
}
else {
- printf("unknown type %i\n", presentType);
+ if (DEBUG_MMS_CLIENT)
+ printf("MMS CLIENT: unknown type %i in access result\n", presentType);
value = MmsValue_newDataAccessError(DATA_ACCESS_ERROR_OBJECT_VALUE_INVALID);
}
@@ -254,21 +361,20 @@ mmsClient_parseReadResponse(ByteBuffer* message, uint32_t* invokeId, bool create
asn_dec_rval_t rval = ber_decode(NULL, &asn_DEF_MmsPdu,
(void**) &mmsPdu, ByteBuffer_getBuffer(message), ByteBuffer_getSize(message));
- if (rval.code != RC_OK)
- return NULL;
-
- if (mmsPdu->present == MmsPdu_PR_confirmedResponsePdu) {
+ if (rval.code == RC_OK) {
+ if (mmsPdu->present == MmsPdu_PR_confirmedResponsePdu) {
- if (invokeId != NULL)
- *invokeId = mmsClient_getInvokeId(&mmsPdu->choice.confirmedResponsePdu);
+ if (invokeId != NULL)
+ *invokeId = mmsClient_getInvokeId(&mmsPdu->choice.confirmedResponsePdu);
- if (mmsPdu->choice.confirmedResponsePdu.confirmedServiceResponse.present == ConfirmedServiceResponse_PR_read) {
- ReadResponse_t* response = &(mmsPdu->choice.confirmedResponsePdu.confirmedServiceResponse.choice.read);
+ if (mmsPdu->choice.confirmedResponsePdu.confirmedServiceResponse.present == ConfirmedServiceResponse_PR_read) {
+ ReadResponse_t* response = &(mmsPdu->choice.confirmedResponsePdu.confirmedServiceResponse.choice.read);
- int elementCount = response->listOfAccessResult.list.count;
+ int elementCount = response->listOfAccessResult.list.count;
- valueList = mmsClient_parseListOfAccessResults(response->listOfAccessResult.list.array,
- elementCount, createArray);
+ valueList = mmsClient_parseListOfAccessResults(response->listOfAccessResult.list.array,
+ elementCount, createArray);
+ }
}
}
diff --git a/src/mms/iso_mms/common/mms_common_msg.c b/src/mms/iso_mms/common/mms_common_msg.c
index 33571c86..bb6a90d9 100644
--- a/src/mms/iso_mms/common/mms_common_msg.c
+++ b/src/mms/iso_mms/common/mms_common_msg.c
@@ -1,7 +1,7 @@
/*
* mms_common_msg.c
*
- * Copyright 2013-2018 Michael Zillgith
+ * Copyright 2013-2019 Michael Zillgith
*
* This file is part of libIEC61850.
*
@@ -185,113 +185,192 @@ mmsMsg_parseDataElement(Data_t* dataElement)
{
MmsValue* value = NULL;
- if (dataElement->present == Data_PR_structure) {
- value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
+ if (dataElement->present == Data_PR_array) {
- int componentCount = dataElement->choice.structure->list.count;
+ int componentCount = dataElement->choice.array->list.count;
+
+ if (componentCount > 0) {
+ value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
- value->type = MMS_STRUCTURE;
- value->value.structure.size = componentCount;
- value->value.structure.components = (MmsValue**) GLOBAL_CALLOC(componentCount, sizeof(MmsValue*));
+ value->type = MMS_ARRAY;
+ value->value.structure.size = componentCount;
+ value->value.structure.components = (MmsValue**) GLOBAL_CALLOC(componentCount, sizeof(MmsValue*));
- int i;
+ int i;
+
+ for (i = 0; i < componentCount; i++) {
+ value->value.structure.components[i] =
+ mmsMsg_parseDataElement(dataElement->choice.array->list.array[i]);
- for (i = 0; i < componentCount; i++) {
- value->value.structure.components[i] =
- mmsMsg_parseDataElement(dataElement->choice.structure->list.array[i]);
+ if (value->value.structure.components[i] == NULL) {
+ MmsValue_delete(value);
+ value = NULL;
+ break;
+ }
+ }
+ }
+ else {
+ if (DEBUG_MMS_CLIENT)
+ printf("MMS CLIENT: error parsing data element (invalid array size)!\n");
}
+
}
- else if (dataElement->present == Data_PR_array) {
- value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
+ else if (dataElement->present == Data_PR_structure) {
- int componentCount = dataElement->choice.array->list.count;
+ int componentCount = dataElement->choice.structure->list.count;
+
+ if (componentCount > 0) {
+ value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
+
+ value->type = MMS_STRUCTURE;
+ value->value.structure.size = componentCount;
+ value->value.structure.components = (MmsValue**) GLOBAL_CALLOC(componentCount, sizeof(MmsValue*));
- value->type = MMS_ARRAY;
- value->value.structure.size = componentCount;
- value->value.structure.components = (MmsValue**) GLOBAL_CALLOC(componentCount, sizeof(MmsValue*));
+ int i;
- int i;
+ for (i = 0; i < componentCount; i++) {
+ value->value.structure.components[i] =
+ mmsMsg_parseDataElement(dataElement->choice.structure->list.array[i]);
- for (i = 0; i < componentCount; i++) {
- value->value.structure.components[i] =
- mmsMsg_parseDataElement(dataElement->choice.array->list.array[i]);
+ if (value->value.structure.components[i] == NULL) {
+ MmsValue_delete(value);
+ value = NULL;
+ break;
+ }
+ }
+ }
+ else {
+ if (DEBUG_MMS_CLIENT)
+ printf("MMS CLIENT: error parsing data element (invalid structure size)!\n");
}
}
- else {
- if (dataElement->present == Data_PR_integer) {
+ else if (dataElement->present == Data_PR_integer) {
+
+ if (dataElement->choice.integer.size > 0) {
Asn1PrimitiveValue* berInteger = BerInteger_createFromBuffer(
dataElement->choice.integer.buf, dataElement->choice.integer.size);
value = MmsValue_newIntegerFromBerInteger(berInteger);
}
- else if (dataElement->present == Data_PR_unsigned) {
+ else {
+ if (DEBUG_MMS_CLIENT)
+ printf("MMS CLIENT: error parsing data element (invalid integer size)!\n");
+ }
+ }
+ else if (dataElement->present == Data_PR_unsigned) {
+
+ if (dataElement->choice.Unsigned.size > 0) {
Asn1PrimitiveValue* berInteger = BerInteger_createFromBuffer(
dataElement->choice.Unsigned.buf, dataElement->choice.Unsigned.size);
value = MmsValue_newUnsignedFromBerInteger(berInteger);
}
- else if (dataElement->present == Data_PR_visiblestring) {
+ else {
+ if (DEBUG_MMS_CLIENT)
+ printf("MMS CLIENT: error parsing data element (invalid unsigned size)!\n");
+ }
+ }
+ else if (dataElement->present == Data_PR_visiblestring) {
+
+ if (dataElement->choice.visiblestring.size >= 0) {
value = MmsValue_newVisibleStringFromByteArray(dataElement->choice.visiblestring.buf,
dataElement->choice.visiblestring.size);
}
- else if (dataElement->present == Data_PR_mMSString) {
+ }
+ else if (dataElement->present == Data_PR_mMSString) {
+
+ if ( dataElement->choice.mMSString.size >= 0) {
value = MmsValue_newMmsStringFromByteArray(dataElement->choice.mMSString.buf,
dataElement->choice.mMSString.size);
}
- else if (dataElement->present == Data_PR_bitstring) {
- value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
+ }
+ else if (dataElement->present == Data_PR_bitstring) {
+
+ int size = dataElement->choice.bitstring.size;
+
+ if (size > 0) {
- value->type = MMS_BIT_STRING;
- int size = dataElement->choice.bitstring.size;
+ int maxSize = (size * 8);
+ int bitSize = maxSize - dataElement->choice.bitstring.bits_unused;
- value->value.bitString.size = (size * 8)
- - dataElement->choice.bitstring.bits_unused;
+ if ((bitSize > 0) && (maxSize >= bitSize)) {
+ value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
+
+ value->type = MMS_BIT_STRING;
- value->value.bitString.buf = (uint8_t*) GLOBAL_MALLOC(size);
- memcpy(value->value.bitString.buf,
- dataElement->choice.bitstring.buf, size);
+ value->value.bitString.size = bitSize;
+ value->value.bitString.buf = (uint8_t*) GLOBAL_MALLOC(size);
+ memcpy(value->value.bitString.buf,
+ dataElement->choice.bitstring.buf, size);
+ }
+ else {
+ if (DEBUG_MMS_CLIENT)
+ printf("MMS CLIENT: error parsing data element (bit string padding problem)!\n");
+ }
}
- else if (dataElement->present == Data_PR_floatingpoint) {
- value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
- int size = dataElement->choice.floatingpoint.size;
+ else {
+ if (DEBUG_MMS_CLIENT)
+ printf("MMS CLIENT: error parsing data element (bit string size 0 or negative)!\n");
+ }
+ }
+ else if (dataElement->present == Data_PR_floatingpoint) {
+
+ int size = dataElement->choice.floatingpoint.size;
+ if (size == 5) { /* FLOAT32 */
+
+ value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
value->type = MMS_FLOAT;
- if (size == 5) { /* FLOAT32 */
- value->value.floatingPoint.formatWidth = 32;
- value->value.floatingPoint.exponentWidth = dataElement->choice.floatingpoint.buf[0];
+ value->value.floatingPoint.formatWidth = 32;
+ value->value.floatingPoint.exponentWidth = dataElement->choice.floatingpoint.buf[0];
- uint8_t* floatBuf = (dataElement->choice.floatingpoint.buf + 1);
+ uint8_t* floatBuf = (dataElement->choice.floatingpoint.buf + 1);
- value->value.floatingPoint.buf = (uint8_t*) GLOBAL_MALLOC(4);
+ value->value.floatingPoint.buf = (uint8_t*) GLOBAL_MALLOC(4);
#if (ORDER_LITTLE_ENDIAN == 1)
- memcpyReverseByteOrder(value->value.floatingPoint.buf, floatBuf, 4);
+ memcpyReverseByteOrder(value->value.floatingPoint.buf, floatBuf, 4);
#else
- memcpy(value->value.floatingPoint.buf, floatBuf, 4);
+ memcpy(value->value.floatingPoint.buf, floatBuf, 4);
#endif
- }
+ }
+
+ if (size == 9) { /* FLOAT64 */
+
+ value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
+ value->type = MMS_FLOAT;
- if (size == 9) { /* FLOAT64 */
- value->value.floatingPoint.formatWidth = 64;
- value->value.floatingPoint.exponentWidth = dataElement->choice.floatingpoint.buf[0];
+ value->value.floatingPoint.formatWidth = 64;
+ value->value.floatingPoint.exponentWidth = dataElement->choice.floatingpoint.buf[0];
- uint8_t* floatBuf = (dataElement->choice.floatingpoint.buf + 1);
+ uint8_t* floatBuf = (dataElement->choice.floatingpoint.buf + 1);
- value->value.floatingPoint.buf = (uint8_t*) GLOBAL_MALLOC(8);
+ value->value.floatingPoint.buf = (uint8_t*) GLOBAL_MALLOC(8);
#if (ORDER_LITTLE_ENDIAN == 1)
- memcpyReverseByteOrder(value->value.floatingPoint.buf, floatBuf, 8);
+ memcpyReverseByteOrder(value->value.floatingPoint.buf, floatBuf, 8);
#else
- memcpy(value->value.floatingPoint.buf, floatBuf, 8);
+ memcpy(value->value.floatingPoint.buf, floatBuf, 8);
#endif
- }
}
- else if (dataElement->present == Data_PR_utctime) {
+ }
+ else if (dataElement->present == Data_PR_utctime) {
+
+ int size = dataElement->choice.utctime.size;
+
+ if (size == 8) {
value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
value->type = MMS_UTC_TIME;
memcpy(value->value.utcTime, dataElement->choice.utctime.buf, 8);
}
- else if (dataElement->present == Data_PR_octetstring) {
+ else {
+ if (DEBUG_MMS_CLIENT)
+ printf("MMS CLIENT: error parsing UTC time (size is %i instead of 8\n", size);
+ }
+ }
+ else if (dataElement->present == Data_PR_octetstring) {
+
+ if (dataElement->choice.octetstring.size >= 0) {
value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
value->type = MMS_OCTET_STRING;
int size = dataElement->choice.octetstring.size;
@@ -300,20 +379,33 @@ mmsMsg_parseDataElement(Data_t* dataElement)
value->value.octetString.buf = (uint8_t*) GLOBAL_MALLOC(size);
memcpy(value->value.octetString.buf, dataElement->choice.octetstring.buf, size);
}
- else if (dataElement->present == Data_PR_binarytime) {
- int size = dataElement->choice.binarytime.size;
- if (size <= 6) {
- value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
- value->type = MMS_BINARY_TIME;
- value->value.binaryTime.size = size;
- memcpy(value->value.binaryTime.buf, dataElement->choice.binarytime.buf, size);
- }
+ }
+ else if (dataElement->present == Data_PR_binarytime) {
+ int size = dataElement->choice.binarytime.size;
+
+ if ((size == 4) || (size == 6)) {
+ value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
+ value->type = MMS_BINARY_TIME;
+ value->value.binaryTime.size = size;
+ memcpy(value->value.binaryTime.buf, dataElement->choice.binarytime.buf, size);
}
- else if (dataElement->present == Data_PR_boolean) {
- value = MmsValue_newBoolean(dataElement->choice.boolean);
+ else {
+ if (DEBUG_MMS_CLIENT)
+ printf("MMS CLIENT: error parsing binary time (size must be 4 or 6, is %i\n", size);
}
+ }
+ else if (dataElement->present == Data_PR_boolean) {
+ value = MmsValue_newBoolean(dataElement->choice.boolean);
+ }
+ else if (dataElement->present == Data_PR_booleanArray) {
+ if (DEBUG_MMS_CLIENT)
+ printf("MMS CLIENT: unsupported type - boolean-array\n");
+ }
+ if (DEBUG_MMS_CLIENT) {
+ if (value == NULL)
+ printf("MMS CLIENT: error parsing data element\n");
}
return value;
diff --git a/src/mms/iso_mms/common/mms_value.c b/src/mms/iso_mms/common/mms_value.c
index f6f315cf..72d577ba 100644
--- a/src/mms/iso_mms/common/mms_value.c
+++ b/src/mms/iso_mms/common/mms_value.c
@@ -1,7 +1,7 @@
/*
* mms_value.c
*
- * Copyright 2013-2018 Michael Zillgith
+ * Copyright 2013-2019 Michael Zillgith
*
* This file is part of libIEC61850.
*
@@ -1076,6 +1076,9 @@ MmsValue_cloneToBuffer(const MmsValue* self, uint8_t* destinationAddress)
MmsValue*
MmsValue_clone(const MmsValue* self)
{
+ if (self == NULL)
+ return NULL;
+
MmsValue* newValue = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
if (newValue == NULL)
@@ -1179,6 +1182,9 @@ MmsValue_deleteIfNotNull(MmsValue* self)
void
MmsValue_delete(MmsValue* self)
{
+ if (self == NULL)
+ return;
+
switch (self->type)
{
case MMS_INTEGER:
@@ -1997,6 +2003,16 @@ MmsValue_getTypeString(MmsValue* self)
const char*
MmsValue_printToBuffer(const MmsValue* self, char* buffer, int bufferSize)
{
+ if (self == NULL) {
+ strncpy(buffer, "(null)", bufferSize);
+
+ /* Ensure buffer is always 0 terminated */
+ if (bufferSize > 0)
+ buffer[bufferSize - 1] = 0;
+
+ return buffer;
+ }
+
switch (MmsValue_getType(self))
{
case MMS_STRUCTURE: