using System; using System.Runtime.InteropServices; namespace IEC61850 { namespace Common { public class LibIEC61850 { [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] static extern IntPtr LibIEC61850_getVersionString(); /// <summary> /// Get the version string of the native libiec61850 library /// </summary> /// <returns>The version string in format MAJOR.MINOR.PATCH</returns> public static string GetVersionString() { return Marshal.PtrToStringAnsi (LibIEC61850_getVersionString ()); } /// <summary> /// Converts millisecond timestamp to a DateTime object /// </summary> /// <returns>The DateTime object representing the value of the timestamp</returns> /// <param name="msTime">The timestamp in milliseconds since epoch (UTC)</param> public static DateTime MsTimestampToDateTime(ulong msTime) { DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); ulong seconds = msTime / 1000; ulong millies = msTime % 1000; dateTime.AddSeconds ((double) seconds); dateTime.AddMilliseconds((double) millies); return dateTime; } /// <summary> /// Converts a DateTime object in milliseconds since epoch timestamp (UTC) /// </summary> /// <returns>The timestamp in ms</returns> /// <param name="msTime">The DateTime object to convert</param> public static ulong DateTimeToMsTimestamp(DateTime dateTime) { return (ulong) (dateTime.ToUniversalTime ().Subtract (new DateTime (1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds); } } /// <summary> /// MMS data access error for MmsValue type MMS_DATA_ACCESS_ERROR /// </summary> public enum MmsDataAccessError { NO_RESPONSE = -2, /* for server internal purposes only! */ SUCCESS = -1, OBJECT_INVALIDATED = 0, HARDWARE_FAULT = 1, TEMPORARILY_UNAVAILABLE = 2, OBJECT_ACCESS_DENIED = 3, OBJECT_UNDEFINED = 4, INVALID_ADDRESS = 5, TYPE_UNSUPPORTED = 6, TYPE_INCONSISTENT = 7, OBJECT_ATTRIBUTE_INCONSISTENT = 8, OBJECT_ACCESS_UNSUPPORTED = 9, OBJECT_NONE_EXISTENT = 10, OBJECT_VALUE_INVALID = 11, UNKNOWN = 12, } [Flags] public enum TriggerOptions { NONE = 0, /** send report when value of data changed */ DATA_CHANGED = 1, /** send report when quality of data changed */ QUALITY_CHANGED = 2, /** send report when data or quality is updated */ DATA_UPDATE = 4, /** periodic transmission of all data set values */ INTEGRITY = 8, /** general interrogation (on client request) */ GI = 16 } [Flags] public enum ReportOptions { NONE = 0, SEQ_NUM = 1, TIME_STAMP = 2, REASON_FOR_INCLUSION = 4, DATA_SET = 8, DATA_REFERENCE = 16, BUFFER_OVERFLOW = 32, ENTRY_ID = 64, CONF_REV = 128, ALL = 255 } public enum Validity { GOOD = 0, RESERVED = 1, INVALID = 2, QUESTIONABLE = 3 } /// <summary> /// The quality of a data object. /// </summary> public class Quality { private UInt16 value; public Quality (int bitStringValue) { value = (UInt16)bitStringValue; } public Quality () { value = 0; } public Validity GetValidity () { int qualityVal = value & 0x3; return (Validity)qualityVal; } public void SetValidity (Validity validity) { value = (UInt16)(value & 0xfffc); value += (ushort)validity; } } public enum ACSIClass { /** data objects */ ACSI_CLASS_DATA_OBJECT, /** data sets (container for multiple data objects) */ ACSI_CLASS_DATA_SET, /** buffered report control blocks */ ACSI_CLASS_BRCB, /** unbuffered report control blocks */ ACSI_CLASS_URCB, /** log control blocks */ ACSI_CLASS_LCB, /** logs (journals) */ ACSI_CLASS_LOG, /** setting group control blocks */ ACSI_CLASS_SGCB, /** GOOSE control blocks */ ACSI_CLASS_GoCB, /** GSE control blocks */ ACSI_CLASS_GsCB, /** multicast sampled values control blocks */ ACSI_CLASS_MSVCB, /** unicast sampled values control blocks */ ACSI_CLASS_USVCB } public enum FunctionalConstraint { /** Status information */ ST = 0, /** Measurands - analog values */ MX = 1, /** Setpoint */ SP = 2, /** Substitution */ SV = 3, /** Configuration */ CF = 4, /** Description */ DC = 5, /** Setting group */ SG = 6, /** Setting group editable */ SE = 7, /** Service response / Service tracking */ SR = 8, /** Operate received */ OR = 9, /** Blocking */ BL = 10, /** Extended definition */ EX = 11, /** Control */ CO = 12, /** Unicast SV */ US = 13, /** Multicast SV */ MS = 14, /** Unbuffered report */ RP = 15, /** Buffered report */ BR = 16, /** Log control blocks */ LG = 17, /** All FCs - wildcard value */ ALL = 99, NONE = -1 } public enum ControlAddCause { ADD_CAUSE_UNKNOWN = 0, ADD_CAUSE_NOT_SUPPORTED = 1, ADD_CAUSE_BLOCKED_BY_SWITCHING_HIERARCHY = 2, ADD_CAUSE_SELECT_FAILED = 3, ADD_CAUSE_INVALID_POSITION = 4, ADD_CAUSE_POSITION_REACHED = 5, ADD_CAUSE_PARAMETER_CHANGE_IN_EXECUTION = 6, ADD_CAUSE_STEP_LIMIT = 7, ADD_CAUSE_BLOCKED_BY_MODE = 8, ADD_CAUSE_BLOCKED_BY_PROCESS = 9, ADD_CAUSE_BLOCKED_BY_INTERLOCKING = 10, ADD_CAUSE_BLOCKED_BY_SYNCHROCHECK = 11, ADD_CAUSE_COMMAND_ALREADY_IN_EXECUTION = 12, ADD_CAUSE_BLOCKED_BY_HEALTH = 13, ADD_CAUSE_1_OF_N_CONTROL = 14, ADD_CAUSE_ABORTION_BY_CANCEL = 15, ADD_CAUSE_TIME_LIMIT_OVER = 16, ADD_CAUSE_ABORTION_BY_TRIP = 17, ADD_CAUSE_OBJECT_NOT_SELECTED = 18, ADD_CAUSE_OBJECT_ALREADY_SELECTED = 19, ADD_CAUSE_NO_ACCESS_AUTHORITY = 20, ADD_CAUSE_ENDED_WITH_OVERSHOOT = 21, ADD_CAUSE_ABORTION_DUE_TO_DEVIATION = 22, ADD_CAUSE_ABORTION_BY_COMMUNICATION_LOSS = 23, ADD_CAUSE_ABORTION_BY_COMMAND = 24, ADD_CAUSE_NONE = 25, ADD_CAUSE_INCONSISTENT_PARAMETERS = 26, ADD_CAUSE_LOCKED_BY_OTHER_CLIENT = 27 } /// <summary> /// Object reference. Helper function to handle object reference strings. /// </summary> public static class ObjectReference { /// <summary> /// Get the name part of an object reference with appended FC /// </summary> /// <returns> /// The element name. /// </returns> /// <param name='objectReferenceWithFc'> /// Object reference with appended fc. /// </param> public static string getElementName (string objectReferenceWithFc) { int fcPartStartIndex = objectReferenceWithFc.IndexOf('['); if (fcPartStartIndex == -1) return objectReferenceWithFc; return objectReferenceWithFc.Substring(0, fcPartStartIndex); } /// <summary> /// Get the FC of an object reference with appended FC. /// </summary> /// <returns> /// The FC /// </returns> /// <param name='objectReferenceWithFc'> /// Object reference with FC. /// </param> public static FunctionalConstraint getFC (string objectReferenceWithFc) { int fcPartStartIndex = objectReferenceWithFc.IndexOf('['); if (fcPartStartIndex == -1) return FunctionalConstraint.NONE; string fcString = objectReferenceWithFc.Substring(fcPartStartIndex + 1 , 2); try { return (FunctionalConstraint) Enum.Parse(typeof(FunctionalConstraint), fcString); } catch(ArgumentException) { return FunctionalConstraint.NONE; } } } } }