예제 #1
0
        public static string ToString(DegreeMinutesSeconds dms, AngleFormat format, int precision)
        {
            switch (format)
            {
            // todo here do we need to combine min and sec ??? or we need diffrent format option
            case AngleFormat.Degrees:
                return(string.Format("{0:D}°", dms.Degrees));

            case AngleFormat.DegreesMinutes:
                return(string.Format("{0:D}°{1:D}'", dms.Degrees, dms.Minutes));

            case AngleFormat.DegreesMinutesSeconds:
                var secondsPrecisionFormat = "F" + Math.Abs(precision).ToString("D");

                //string d = dms.Degrees.ToString("");

                //CultureInfo currentCulture = CultureInfo.CurrentCulture;
                var stringFormat = "{0:F0}° {1:F0}' {2:" + secondsPrecisionFormat + "}\"";
                return(string.Format(stringFormat, dms.Degrees, dms.Minutes, dms.Seconds));

            case AngleFormat.Radians:
                // todo convert to radians ??
                break;
            }

            throw new ArgumentOutOfRangeException("format");
        }
예제 #2
0
        public void SetAngle(double input, AngleFormat format = AngleFormat.Unit)
        {
            bool   inverted = input < 0;
            double absolute = (inverted) ? -input : input;

            switch (format)
            {
            case AngleFormat.Unit:
                angle = (uint)((absolute % 1) * uint.MaxValue);
                break;

            case AngleFormat.Radians:
                angle = (uint)(((absolute / (Math.PI * 2)) % 1) * uint.MaxValue);
                break;

            case AngleFormat.Degrees:
                angle = (uint)(((absolute / 360) % 1) * uint.MaxValue);
                break;

            default:
                throw new NotImplementedException(format + " format is not supportd by this method.(unreachable code)");
            }
            if (inverted)
            {
                angle = unchecked (uint.MaxValue - angle + 1);
            }
        }
예제 #3
0
 /// <summary>
 /// Creates a new <see cref="ConnectionParameters"/>.
 /// </summary>
 public ConnectionParameters()
 {
     m_useETRConfiguration = DefaultUseETRConfiguration;
     m_guessConfiguration  = DefaultGuessConfiguration;
     m_parseRedundantASDUs = DefaultParseRedundantASDUs;
     m_ignoreSignatureValidationFailures  = DefaultIgnoreSignatureValidationFailures;
     m_ignoreSampleSizeValidationFailures = DefaultIgnoreSampleSizeValidationFailures;
     m_phasorAngleFormat = (AngleFormat)Enum.Parse(typeof(AngleFormat), DefaultPhasorAngleFormat, true);
 }
예제 #4
0
 /// <summary>
 /// Creates a new <see cref="ConnectionParameters"/> from serialization parameters.
 /// </summary>
 /// <param name="info">The <see cref="SerializationInfo"/> with populated with data.</param>
 /// <param name="context">The source <see cref="StreamingContext"/> for this deserialization.</param>
 protected ConnectionParameters(SerializationInfo info, StreamingContext context)
 {
     // Deserialize connection parameters
     m_useETRConfiguration = info.GetOrDefault("useETRConfiguration", DefaultUseETRConfiguration);
     m_guessConfiguration  = info.GetOrDefault("guessConfiguration", DefaultGuessConfiguration);
     m_parseRedundantASDUs = info.GetOrDefault("parseRedundantASDUs", DefaultParseRedundantASDUs);
     m_ignoreSignatureValidationFailures  = info.GetOrDefault("ignoreSignatureValidationFailures", DefaultIgnoreSignatureValidationFailures);
     m_ignoreSampleSizeValidationFailures = info.GetOrDefault("ignoreSampleSizeValidationFailures", DefaultIgnoreSampleSizeValidationFailures);
     m_phasorAngleFormat = info.GetOrDefault("phasorAngleFormat", (AngleFormat)Enum.Parse(typeof(AngleFormat), DefaultPhasorAngleFormat, true));
 }
예제 #5
0
        /// <summary>
        /// Gives a text representation of the instance.
        /// </summary>
        /// <param name="angleFormat">A <see cref="AngleFormat" /> member.</param>
        /// <param name="decimalPlaces">The number of decimal places (after decimal point) for the last unit.</param>
        /// <param name="separator">The text between latitude and longitude.</param>
        /// <param name="forceAsciiCharacters">If true: Use 7 Bit ASCII characters only instead of special characters.</param>
        /// <returns>The text representation.</returns>
        public string ToString(
            AngleFormat angleFormat, int decimalPlaces,
            string separator, bool forceAsciiCharacters
            )
        {
            string result =
                GetFormattedText(Latitude, angleFormat, decimalPlaces, forceAsciiCharacters) + " N" +
                separator +
                GetFormattedText(Longitude, angleFormat, decimalPlaces, forceAsciiCharacters) + " E"
            ;

            return(result);
        }
예제 #6
0
        public void AngleFormatTest()
        {
            AngleFormat af = new AngleFormat(AngleFormat.PatternLatitudeDDMMSS);
            String      s1 = String.Format(af, "{0}", Math.PI);

            s1 = String.Format(af, "{0:DdMmSs}", Math.PI);
            Double v1 = af.Parse(s1);

            Assert.AreEqual(Math.PI, v1);

            s1 = String.Format(af, "{0:D°M'S\"N}", -0.9 * Math.PI);
            v1 = af.Parse(s1);
            Assert.AreEqual(-0.9 * Math.PI, v1);
        }
예제 #7
0
        public void SetAngle(uint input, AngleFormat format = AngleFormat.Unit)
        {
            switch (format)
            {
            case AngleFormat.Unit:
                angle = input;
                break;

            case AngleFormat.Radians:
            case AngleFormat.Degrees:
                SetAngle((double)input, format);
                break;

            default:
                throw new NotImplementedException(format + " format is not supportd by this method.(unreachable code)");
            }
        }
예제 #8
0
        public static string ToString(double Angle, AngleFormat Format, string DegreeFormat)
        {
            double absA = Math.Abs(Angle);
            int    deg  = (int)Math.Floor(absA);
            double rem  = 60.0 * (absA - deg);
            int    min  = (int)Math.Floor(rem);

            rem -= min;
            int    hhss;
            string s = (Angle < 0.0) ? "-" : "";

            switch (Format)
            {
            case AngleFormat.DDMMmm:
                hhss = (int)Math.Round(100.0 * rem);
                if (hhss >= 100)
                {
                    hhss -= 100;
                    min++;
                }
                break;

            case AngleFormat.DDMMSS:
            default:
                hhss = (int)Math.Round(60.0 * rem);
                if (hhss >= 60)
                {
                    hhss -= 60;
                    min++;
                }
                break;
            }
            if (min >= 60)
            {
                min -= 60;
                deg++;
            }

            s += deg.ToString(DegreeFormat, CultureInfo.CurrentCulture) + min.ToString("00", CultureInfo.CurrentCulture);
            if (Format == AngleFormat.DDMMmm)
            {
                s += ".";
            }
            s += hhss.ToString("00", CultureInfo.CurrentCulture);
            return(s);
        }
예제 #9
0
        public static string ToString(Degree degree, AngleFormat format, int precision)
        {
            //   DegreeMinutesSeconds dms = ToDDegreeMinutesSeconds(degree);
            switch (format)
            {
            // todo use precision
            case AngleFormat.Degrees:
            case AngleFormat.DegreesMinutes:
            case AngleFormat.DegreesMinutesSeconds:
                return(ToString(ToDDegreeMinutesSeconds(degree), format, precision));

            case AngleFormat.Radians:
                return(ToString((Radian)degree, format, precision));

            default:
                throw new ArgumentOutOfRangeException(nameof(format), format, null);
            }
        }
예제 #10
0
        public double GetAngle(AngleFormat format)
        {
            double temp = angle / (((double)uint.MaxValue) + 1);

            switch (format)
            {
            case AngleFormat.Unit:
                return(temp);

            case AngleFormat.Radians:
                return(temp * (Math.PI * 2));

            case AngleFormat.Degrees:
                return(temp * 360);

            default:
                throw new NotImplementedException(format + " format is not supportd by this method.(unreachable code)");
            }
        }
예제 #11
0
        public static string ToString(Radian radian, AngleFormat format, int precision)
        {
            switch (format)
            {
            case AngleFormat.Radians:
            {
                var formStr = "{0:F" + precision + "}";

                return(string.Format(formStr, radian));
            }

            case AngleFormat.Degrees:
            case AngleFormat.DegreesMinutes:
            case AngleFormat.DegreesMinutesSeconds:
                return(ToString((Degree)radian, format, precision));

            default:
                throw new NotImplementedException();
            }
        }
예제 #12
0
        public static string ToString(double Angle, AngleKind Kind, AngleFormat Format)
        {
            string degFmt;
            char   sign;

            switch (Kind)
            {
            case AngleKind.Latitude:
                degFmt = "00";
                sign   = (Angle < 0.0) ? 'S' : 'N';
                break;

            case AngleKind.Longitude:
            default:
                degFmt = "000";
                sign   = (Angle < 0.0) ? 'W' : 'E';
                break;
            }
            string s = ToString(Math.Abs(Angle), Format, degFmt) + sign;

            return(s);
        }
예제 #13
0
        /// <summary>
        /// Retrieves a formatted text for a degree value
        /// according to a given angle format.
        /// </summary>
        /// <param name="decDegrees">The degree value (with decimal places).</param>
        /// <param name="angleFormat">A <see cref="AngleFormat" /> member.</param>
        /// <param name="decimalPlaces">The number of decimal places (after decimal point) for the last unit.</param>
        /// <param name="forceAsciiCharacters">If true: Use 7 Bit ASCII characters only instead of special characters.</param>
        /// <returns>The formatted text.</returns>
        public static string GetFormattedText(double decDegrees, AngleFormat angleFormat, int decimalPlaces, bool forceAsciiCharacters)
        {
            string degreeSymbol, minuteSymbol, secondsSymbol;

            if (forceAsciiCharacters)
            {
                degreeSymbol  = "d";
                minuteSymbol  = "'";
                secondsSymbol = "\"";
            }
            else
            {
                degreeSymbol  = "\x00B0".ToString();                //DEGREE SIGN
                minuteSymbol  = "\x2032".ToString();                //PRIME
                secondsSymbol = "\x2033".ToString();                //DOUBLE PRIME
            }

            string separator = " ";

            string result;

            switch (angleFormat)
            {
            case AngleFormat.sD:
            {
                bool   isNegative;
                double degrees;
                Utilities.DegreesToD(decDegrees, out isNegative, out degrees);

                result =
                    GetSignSymbol(isNegative) +
                    string.Format(Utilities.GetFormatString(1, decimalPlaces), degrees) + degreeSymbol
                ;
            }
            break;

            case AngleFormat.sDD:
            {
                bool   isNegative;
                double degrees;
                Utilities.DegreesToD(decDegrees, out isNegative, out degrees);

                result =
                    GetSignSymbol(isNegative) +
                    string.Format(Utilities.GetFormatString(2, decimalPlaces), degrees) + degreeSymbol
                ;
            }
            break;

            case AngleFormat.sDM:
            {
                bool   isNegative;
                int    degrees;
                double minutes;
                Utilities.DegreesToDM(decDegrees, out isNegative, out degrees, out minutes);

                Utilities.Round(decimalPlaces, ref degrees, ref minutes);

                result =
                    GetSignSymbol(isNegative) +
                    string.Format(Utilities.GetFormatString(1, 0), degrees) + degreeSymbol + separator +
                    string.Format(Utilities.GetFormatString(1, decimalPlaces), minutes) + minuteSymbol
                ;
            }
            break;

            case AngleFormat.sDDMM:
            {
                bool   isNegative;
                int    degrees;
                double minutes;
                Utilities.DegreesToDM(decDegrees, out isNegative, out degrees, out minutes);

                Utilities.Round(decimalPlaces, ref degrees, ref minutes);

                result =
                    GetSignSymbol(isNegative) +
                    string.Format(Utilities.GetFormatString(2, 0), degrees) + degreeSymbol + separator +
                    string.Format(Utilities.GetFormatString(2, decimalPlaces), minutes) + minuteSymbol
                ;
            }
            break;

            case AngleFormat.sDMS:
            {
                bool   isNegative;
                int    degrees;
                int    minutes;
                double seconds;
                Utilities.DegreesToDMS(decDegrees, out isNegative, out degrees, out minutes, out seconds);

                Utilities.Round(decimalPlaces, ref degrees, ref minutes, ref seconds);

                result =
                    GetSignSymbol(isNegative) +
                    string.Format(Utilities.GetFormatString(1, 0), degrees) + degreeSymbol + separator +
                    string.Format(Utilities.GetFormatString(1, 0), minutes) + minuteSymbol + separator +
                    string.Format(Utilities.GetFormatString(1, decimalPlaces), seconds) + secondsSymbol
                ;
            }
            break;

            case AngleFormat.sDDMMSS:
            {
                bool   isNegative;
                int    degrees;
                int    minutes;
                double seconds;
                Utilities.DegreesToDMS(decDegrees, out isNegative, out degrees, out minutes, out seconds);

                Utilities.Round(decimalPlaces, ref degrees, ref minutes, ref seconds);

                result =
                    GetSignSymbol(isNegative) +
                    string.Format(Utilities.GetFormatString(2, 0), degrees) + degreeSymbol + separator +
                    string.Format(Utilities.GetFormatString(2, 0), minutes) + minuteSymbol + separator +
                    string.Format(Utilities.GetFormatString(2, decimalPlaces), seconds) + secondsSymbol
                ;
            }
            break;

            default:
                throw new NotSupportedException(angleFormat.ToString());
            }

            return(result);
        }
예제 #14
0
 /// <summary>
 /// Creates a new <see cref="ConnectionParameters"/>.
 /// </summary>
 public ConnectionParameters()
 {
     m_useETRConfiguration = DefaultUseETRConfiguration;
     m_guessConfiguration = DefaultGuessConfiguration;
     m_parseRedundantASDUs = DefaultParseRedundantASDUs;
     m_ignoreSignatureValidationFailures = DefaultIgnoreSignatureValidationFailures;
     m_ignoreSampleSizeValidationFailures = DefaultIgnoreSampleSizeValidationFailures;
     m_phasorAngleFormat = (AngleFormat)Enum.Parse(typeof(AngleFormat), DefaultPhasorAngleFormat, true);
 }
예제 #15
0
 public Angle(uint input, AngleFormat format = AngleFormat.Unit) : this()
 {
     SetAngle(input, format);
 }
예제 #16
0
        /// <summary>
        /// Creates a new <see cref="CommonFrameHeader"/> from given <paramref name="buffer"/>.
        /// </summary>
        /// <param name="configurationFrame">IEC 61850-90-5 <see cref="ConfigurationFrame"/> if already parsed.</param>
        /// <param name="useETRConfiguration">Determines if system should find associated ETR file using MSVID with same name for configuration.</param>
        /// <param name="guessConfiguration">Determines if system should try to guess at a possible configuration given payload size.</param>
        /// <param name="parseRedundantASDUs">Determines if system should expose redundantly parsed ASDUs.</param>
        /// <param name="ignoreSignatureValidationFailures">Determines if system should ignore checksum signature validation errors.</param>
        /// <param name="ignoreSampleSizeValidationFailures">Determines if system should ignore sample size validation errors.</param>
        /// <param name="angleFormat">Allows customization of the angle parsing format.</param>
        /// <param name="buffer">Buffer that contains data to parse.</param>
        /// <param name="startIndex">Start index into buffer where valid data begins.</param>
        /// <param name="length">Maximum length of valid data from offset.</param>
        // ReSharper disable once UnusedParameter.Local
        public CommonFrameHeader(ConfigurationFrame configurationFrame, bool useETRConfiguration, bool guessConfiguration, bool parseRedundantASDUs, bool ignoreSignatureValidationFailures, bool ignoreSampleSizeValidationFailures, AngleFormat angleFormat, byte[] buffer, int startIndex, int length)
        {
            const byte VersionNumberMask = (byte)IEC61850_90_5.FrameType.VersionNumberMask;

            // Cache behavioral connection parameters
            m_useETRConfiguration = useETRConfiguration;
            m_guessConfiguration  = guessConfiguration;
            m_parseRedundantASDUs = parseRedundantASDUs;
            m_ignoreSignatureValidationFailures  = ignoreSignatureValidationFailures;
            m_ignoreSampleSizeValidationFailures = ignoreSampleSizeValidationFailures;
            m_angleFormat = angleFormat;

            // Ignore the time base from configuration frame if available.  The timebase is not adjustable for 61850.
            m_timebase = Common.Timebase;

            // See if frame is for a common IEEE C37.118 frame (e.g., for configuration or command)
            if (buffer[startIndex] == PhasorProtocols.Common.SyncByte)
            {
                // Strip out frame type and version information...
                m_frameType = (FrameType)(buffer[startIndex + 1] & ~VersionNumberMask);
                m_version   = (byte)(buffer[startIndex + 1] & VersionNumberMask);

                m_frameLength = BigEndian.ToUInt16(buffer, startIndex + 2);
                m_idCode      = BigEndian.ToUInt16(buffer, startIndex + 4);

                uint secondOfCentury  = BigEndian.ToUInt32(buffer, startIndex + 6);
                uint fractionOfSecond = BigEndian.ToUInt32(buffer, startIndex + 10);
                long ticksBeyondSecond;

                // Without timebase, the best timestamp you can get is down to the whole second
                m_timestamp = (new UnixTimeTag((double)secondOfCentury)).ToDateTime().Ticks;

                // "Actual fractional seconds" are obtained by taking fractionOfSecond and dividing by timebase.
                // Since we are converting to ticks, we need to multiply by Ticks.PerSecond.
                // We do the multiplication first so that the whole operation can be done using integer arithmetic.
                // m_timebase / 2L is added before dividing by timebase in order to round the result.
                ticksBeyondSecond = (fractionOfSecond & ~Common.TimeQualityFlagsMask) * Ticks.PerSecond;
                m_timestamp      += (ticksBeyondSecond + m_timebase / 2L) / m_timebase;

                if ((object)configurationFrame != null)
                {
                    // Hang on to configured frame rate and ticks per frame
                    m_framesPerSecond = configurationFrame.FrameRate;
                    m_ticksPerFrame   = Ticks.PerSecond / (double)m_framesPerSecond;
                }

                m_timeQualityFlags = fractionOfSecond & Common.TimeQualityFlagsMask;
            }
            else if (buffer[startIndex + 1] == Common.CltpTag)
            {
                // Make sure there is enough data to parse session header from frame
                if (length > Common.SessionHeaderSize)
                {
                    // Manually assign frame type - this is an IEC 61850-90-5 data frame
                    m_frameType = IEC61850_90_5.FrameType.DataFrame;

                    // Calculate CLTP tag length
                    int cltpTagLength = buffer[startIndex] + 1;

                    // Initialize buffer parsing index starting past connectionless transport protocol header
                    int index = startIndex + cltpTagLength;

                    // Start calculating total frame length
                    int frameLength = cltpTagLength;

                    // Get session type (Goose, sampled values, etc.)
                    SessionType sessionType = (SessionType)buffer[index++];

                    // Make sure session type is sampled values
                    if (sessionType == SessionType.SampledValues)
                    {
                        byte headerSize = buffer[index];

                        // Make sure header size is standard
                        if (headerSize == Common.SessionHeaderSize)
                        {
                            // Skip common header tag
                            index += 3;

                            // Get SPDU length
                            m_spduLength = BigEndian.ToUInt32(buffer, index);
                            index       += 4;

                            // Add SPDU length to total frame length (updated as of 10/3/2012 to accommodate extra 6 bytes)
                            frameLength += (int)m_spduLength + 8;

                            // Make sure full frame of data is available - cannot calculate full frame length needed for check sum
                            // without the entire frame since signature algorithm calculation length varies by type and size
                            if (length > m_spduLength + 13)
                            {
                                // Get SPDU packet number
                                m_packetNumber = BigEndian.ToUInt32(buffer, index);

                                // Get security algorithm type
                                m_securityAlgorithm = (SecurityAlgorithm)buffer[index + 12];

                                // Get signature algorithm type
                                m_signatureAlgorithm = (SignatureAlgorithm)buffer[index + 13];

                                // Get current key ID
                                m_keyID = BigEndian.ToUInt32(buffer, index + 14);

                                // Add signature calculation result length to total frame length
                                switch (m_signatureAlgorithm)
                                {
                                case SignatureAlgorithm.None:
                                    break;

                                case SignatureAlgorithm.Sha80:
                                    frameLength += 11;
                                    break;

                                case SignatureAlgorithm.Sha128:
                                case SignatureAlgorithm.Aes128:
                                    frameLength += 17;
                                    break;

                                case SignatureAlgorithm.Sha256:
                                    frameLength += 33;
                                    break;

                                case SignatureAlgorithm.Aes64:
                                    frameLength += 9;
                                    break;

                                default:
                                    throw new InvalidOperationException("Invalid IEC 61850-90-5 signature algorithm detected: 0x" + buffer[index].ToString("X").PadLeft(2, '0'));
                                }

                                // Check signature algorithm packet checksum here, this step is skipped in data frame parsing due to non-standard location...
                                if (m_signatureAlgorithm != SignatureAlgorithm.None)
                                {
                                    int packetIndex = startIndex + cltpTagLength;
                                    int hmacIndex   = (int)(packetIndex + m_spduLength + 2);

                                    // Check for signature tag
                                    if (buffer[hmacIndex++] == 0x85)
                                    {
                                        // KeyID is technically a lookup into derived rotating keys, but all these are using dummy key for now
                                        HMAC hmac   = m_signatureAlgorithm <= SignatureAlgorithm.Sha256 ? (HMAC)(new ShaHmac(Common.DummyKey)) : (HMAC)(new AesHmac(Common.DummyKey));
                                        int  result = 0;

                                        switch (m_signatureAlgorithm)
                                        {
                                        case SignatureAlgorithm.None:
                                            break;

                                        case SignatureAlgorithm.Aes64:
                                            m_sourceHash     = buffer.BlockCopy(hmacIndex, 8);
                                            m_calculatedHash = hmac.ComputeHash(buffer, packetIndex, (int)m_spduLength).BlockCopy(0, 8);
                                            result           = m_sourceHash.CompareTo(0, m_calculatedHash, 0, 8);
                                            break;

                                        case SignatureAlgorithm.Sha80:
                                            m_sourceHash     = buffer.BlockCopy(hmacIndex, 10);
                                            m_calculatedHash = hmac.ComputeHash(buffer, packetIndex, (int)m_spduLength).BlockCopy(0, 10);
                                            result           = m_sourceHash.CompareTo(0, m_calculatedHash, 0, 10);
                                            break;

                                        case SignatureAlgorithm.Sha128:
                                        case SignatureAlgorithm.Aes128:
                                            m_sourceHash     = buffer.BlockCopy(hmacIndex, 16);
                                            m_calculatedHash = hmac.ComputeHash(buffer, packetIndex, (int)m_spduLength).BlockCopy(0, 16);
                                            result           = m_sourceHash.CompareTo(0, m_calculatedHash, 0, 16);
                                            break;

                                        case SignatureAlgorithm.Sha256:
                                            m_sourceHash     = buffer.BlockCopy(hmacIndex, 32);
                                            m_calculatedHash = hmac.ComputeHash(buffer, packetIndex, (int)m_spduLength).BlockCopy(0, 32);
                                            result           = m_sourceHash.CompareTo(0, m_calculatedHash, 0, 32);
                                            break;

                                        default:
                                            throw new NotSupportedException(string.Format("IEC 61850-90-5 signature algorithm \"{0}\" is not currently supported: ", m_signatureAlgorithm));
                                        }

                                        if (result != 0 && !m_ignoreSignatureValidationFailures)
                                        {
                                            throw new CrcException("Invalid binary image detected - IEC 61850-90-5 check sum does not match.");
                                        }
                                    }
                                    else
                                    {
                                        throw new CrcException("Invalid binary image detected - expected IEC 61850-90-5 check sum does not exist.");
                                    }
                                }

                                // Get payload length
                                index       += 18;
                                m_dataLength = (ushort)BigEndian.ToUInt32(buffer, index);
                                index       += 4;

                                // Confirm payload type tag is sampled values
                                if (buffer[index] != 0x82)
                                {
                                    throw new InvalidOperationException("Encountered a payload that is not tagged 0x82 for sampled values: 0x" + buffer[index].ToString("X").PadLeft(2, '0'));
                                }

                                index++;

                                // Get simulated bit value
                                m_simulatedData = buffer[index++] != 0;

                                // Get application ID
                                m_applicationID = BigEndian.ToUInt16(buffer, index);
                                index          += 2;

                                // Get ASDU payload size
                                m_payloadSize = BigEndian.ToUInt16(buffer, index);
                                index        += 2;

                                // Validate sampled value PDU tag exists and skip past it
                                buffer.ValidateTag(SampledValueTag.SvPdu, ref index);

                                // Parse number of ASDUs tag
                                m_asduCount = buffer.ParseByteTag(SampledValueTag.AsduCount, ref index);

                                if (m_asduCount == 0)
                                {
                                    throw new InvalidOperationException("Total number of ADSUs must be greater than zero.");
                                }

                                // Validate sequence of ASDU tag exists and skip past it
                                buffer.ValidateTag(SampledValueTag.SequenceOfAsdu, ref index);

                                // Set header length
                                m_headerLength = (ushort)(index - startIndex);

                                // Set calculated frame length
                                m_frameLength = (ushort)frameLength;
                            }
                        }
                        else
                        {
                            throw new InvalidOperationException("Bad data stream, encountered an invalid session header size: " + headerSize);
                        }
                    }
                    else
                    {
                        throw new InvalidOperationException(string.Format("This library can only parse IEC 61850-90-5 sampled value sessions, type \"{0}\" is not supported.", sessionType));
                    }
                }
            }
            else
            {
                throw new InvalidOperationException("Bad data stream, expected sync byte 0xAA or 0x01 as first byte in IEC 61850-90-5 frame, got 0x" + buffer[startIndex].ToString("X").PadLeft(2, '0'));
            }
        }
예제 #17
0
 /// <summary>
 /// Creates a new <see cref="ConnectionParameters"/> from serialization parameters.
 /// </summary>
 /// <param name="info">The <see cref="SerializationInfo"/> with populated with data.</param>
 /// <param name="context">The source <see cref="StreamingContext"/> for this deserialization.</param>
 protected ConnectionParameters(SerializationInfo info, StreamingContext context)
 {
     // Deserialize connection parameters
     m_useETRConfiguration = info.GetOrDefault("useETRConfiguration", DefaultUseETRConfiguration);
     m_guessConfiguration = info.GetOrDefault("guessConfiguration", DefaultGuessConfiguration);
     m_parseRedundantASDUs = info.GetOrDefault("parseRedundantASDUs", DefaultParseRedundantASDUs);
     m_ignoreSignatureValidationFailures = info.GetOrDefault("ignoreSignatureValidationFailures", DefaultIgnoreSignatureValidationFailures);
     m_ignoreSampleSizeValidationFailures = info.GetOrDefault("ignoreSampleSizeValidationFailures", DefaultIgnoreSampleSizeValidationFailures);
     m_phasorAngleFormat = info.GetOrDefault("phasorAngleFormat", (AngleFormat)Enum.Parse(typeof(AngleFormat), DefaultPhasorAngleFormat, true));
 }