Ejemplo n.º 1
0
        // Static Methods

        // Delegate handler to create a new IEC 61850-90-5 data cell
        internal static IDataCell CreateNewCell(IChannelFrame parent, IChannelFrameParsingState <IDataCell> state, int index, byte[] buffer, int startIndex, out int parsedLength)
        {
            IDataFrameParsingState parsingState      = state as IDataFrameParsingState;
            IConfigurationCell     configurationCell = null;

            // With or without an associated configuration, we'll parse the data cell
            if (parsingState != null && parsingState.ConfigurationFrame != null)
            {
                configurationCell = parsingState.ConfigurationFrame.Cells[index];
            }

            DataCell dataCell = new DataCell(parent as IDataFrame, configurationCell);

            parsedLength = dataCell.ParseBinaryImage(buffer, startIndex, 0);

            return(dataCell);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Parses the binary image.
        /// </summary>
        /// <param name="buffer">Binary image to parse.</param>
        /// <param name="startIndex">Start index into <paramref name="buffer"/> to begin parsing.</param>
        /// <param name="length">Length of valid data within <paramref name="buffer"/>.</param>
        /// <returns>The length of the data that was parsed.</returns>
        /// <remarks>
        /// This method is overridden to ensure assignment of configuration frame.
        /// </remarks>
        public override int ParseBinaryImage(byte[] buffer, int startIndex, int length)
        {
            // Make sure configuration frame gets assigned before parsing begins...
            IDataFrameParsingState state = State;
            IConfigurationFrame    configurationFrame = state.ConfigurationFrame;

            if (configurationFrame != null)
            {
                ConfigurationFrame = configurationFrame;

                // Handle normal parsing
                return(base.ParseBinaryImage(buffer, startIndex, length));
            }

            // Otherwise we just skip parsing this frame...
            return(state.ParsedBinaryLength);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Parses the binary header image.
        /// </summary>
        /// <param name="buffer">Binary image to parse.</param>
        /// <param name="startIndex">Start index into <paramref name="buffer"/> to begin parsing.</param>
        /// <param name="length">Length of valid data within <paramref name="buffer"/>.</param>
        /// <returns>The length of the data that was parsed.</returns>
        protected override int ParseHeaderImage(byte[] buffer, int startIndex, int length)
        {
            IDataFrameParsingState state = State;
            ConfigurationFrame     configurationFrame = state.ConfigurationFrame as ConfigurationFrame;

            // Check for unlikely occurrence of unexpected configuration frame type
            if ((object)configurationFrame == null)
            {
                throw new InvalidOperationException("Unexpected configuration frame encountered - BPA PDCstream configuration frame expected, cannot parse data frame.");
            }

            if (m_usePhasorDataFileFormat)
            {
                // Because in cases where PDCxchng is being used the data cell count will be smaller than the
                // configuration cell count - we save this count to calculate the offsets later
                state.CellCount = unchecked ((int)configurationFrame.CommonHeader.PmuCount);

                if (state.CellCount > configurationFrame.Cells.Count)
                {
                    throw new InvalidOperationException("Stream/Config File Mismatch: PMU count (" + state.CellCount + ") in stream does not match defined count in configuration file (" + configurationFrame.Cells.Count + ")");
                }

                return(CommonFrameHeader.FixedLength);
            }

            // Only need to parse what wasn't already parsed in common frame header
            int index = startIndex + CommonFrameHeader.FixedLength;

            // Parse frame timestamp
            uint secondOfCentury = BigEndian.ToUInt32(buffer, index);

            m_sampleNumber = BigEndian.ToUInt16(buffer, index + 4);
            index         += 6;

            if (configurationFrame.RevisionNumber == RevisionNumber.Revision0)
            {
                Timestamp = (new NtpTimeTag(secondOfCentury, 0)).ToDateTime().Ticks + (long)((m_sampleNumber - 1) * configurationFrame.TicksPerFrame);
            }
            else
            {
                Timestamp = (new UnixTimeTag(secondOfCentury)).ToDateTime().Ticks + (long)((m_sampleNumber - 1) * configurationFrame.TicksPerFrame);
            }

            // Because in cases where PDCxchng is being used the data cell count will be smaller than the
            // configuration cell count - we save this count to calculate the offsets later
            state.CellCount = BigEndian.ToUInt16(buffer, index);
            index          += 2;

            if (state.CellCount > configurationFrame.Cells.Count)
            {
                throw new InvalidOperationException("Stream/Config File Mismatch: PMU count (" + state.CellCount + ") in stream does not match defined count in configuration file (" + configurationFrame.Cells.Count + ")");
            }

            // We'll at least retrieve legacy labels if defined (might be useful for debugging dynamic changes in data-stream)
            if (configurationFrame.StreamType == StreamType.Legacy)
            {
                m_legacyLabels = new string[state.CellCount];

                for (int x = 0; x < state.CellCount; x++)
                {
                    m_legacyLabels[x] = Encoding.ASCII.GetString(buffer, index, 4);
                    // We don't need offsets, so we skip them...
                    index += 8;
                }
            }

            return(index - startIndex);
        }