//****************************************************************************************************** // DataFrame.cs - Gbtc // // Copyright © 2012, Grid Protection Alliance. All Rights Reserved. // // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See // the NOTICE file distributed with this work for additional information regarding copyright ownership. // The GPA licenses this file to you under the MIT License (MIT), the "License"; you may // not use this file except in compliance with the License. You may obtain a copy of the License at: // // http://www.opensource.org/licenses/MIT // // Unless agreed to in writing, the subject software distributed under the License is distributed on an // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the // License for the specific language governing permissions and limitations. // // Code Modification History: // ---------------------------------------------------------------------------------------------------- // 01/14/2005 - J. Ritchie Carroll // Generated original version of source code. // 09/15/2009 - Stephen C. Wills // Added new header and license agreement. // 12/17/2012 - Starlynn Danyelle Gilliam // Modified Header. // //****************************************************************************************************** using System; using System.Collections.Generic; using System.ComponentModel; using System.Runtime.Serialization; using GSF.IO.Checksums; using GSF.Parsing; namespace GSF.PhasorProtocols.IEEE1344 { /// /// Represents the IEEE 1344 implementation of a that can be sent or received. /// [Serializable] public class DataFrame : DataFrameBase, ISupportSourceIdentifiableFrameImage { #region [ Members ] // Fields private CommonFrameHeader m_frameHeader; #endregion #region [ Constructors ] /// /// Creates a new . /// /// /// This constructor is used by to parse an IEEE 1344 data frame. /// [EditorBrowsable(EditorBrowsableState.Never)] public DataFrame() : base(new DataCellCollection(), 0, null) { } /// /// Creates a new from specified parameters. /// /// The exact timestamp, in , of the data represented by this . /// The associated with this . /// /// This constructor is used by a consumer to generate an IEEE 1344 data frame. /// public DataFrame(Ticks timestamp, ConfigurationFrame configurationFrame) : base(new DataCellCollection(), timestamp, configurationFrame) { } /// /// Creates a new from serialization parameters. /// /// The with populated with data. /// The source for this deserialization. protected DataFrame(SerializationInfo info, StreamingContext context) : base(info, context) { // Deserialize data frame m_frameHeader = (CommonFrameHeader)info.GetValue("frameHeader", typeof(CommonFrameHeader)); } #endregion #region [ Properties ] /// /// Gets reference to the for this . /// public new DataCellCollection Cells => base.Cells as DataCellCollection; /// /// Gets or sets associated with this . /// public new ConfigurationFrame ConfigurationFrame { get => base.ConfigurationFrame as ConfigurationFrame; set => base.ConfigurationFrame = value; } /// /// Gets the numeric ID code for this . /// public new ulong IDCode => ConfigurationFrame.IDCode; /// /// Gets or sets exact timestamp, in ticks, of the data represented by this . /// /// /// The value of this property represents the number of 100-nanosecond intervals that have elapsed since 12:00:00 midnight, January 1, 0001. /// public override Ticks Timestamp { get => CommonHeader.Timestamp; set { // Keep timestamp updates synchronized... CommonHeader.Timestamp = value; base.Timestamp = value; } } /// /// Gets the timestamp of this frame in NTP format. /// public new NtpTimeTag TimeTag => CommonHeader.TimeTag; /// /// Gets the identifier that is used to identify the IEEE 1344 frame. /// public FrameType TypeID => IEEE1344.FrameType.DataFrame; /// /// Gets or sets current . /// public CommonFrameHeader CommonHeader { // Make sure frame header exists - using base class timestamp to // prevent recursion (m_frameHeader doesn't exist yet) get => m_frameHeader ??= new CommonFrameHeader(TypeID, base.Timestamp); set { m_frameHeader = value; if (m_frameHeader == null) return; State = m_frameHeader.State as IDataFrameParsingState; base.Timestamp = m_frameHeader.Timestamp; } } // This interface implementation satisfies ISupportFrameImage.CommonHeader ICommonHeader ISupportFrameImage.CommonHeader { get => CommonHeader; set => CommonHeader = value as CommonFrameHeader; } /// /// Gets the length of the . /// protected override int HeaderLength => CommonFrameHeader.FixedLength; /// /// Gets the binary header image of the object. /// protected override byte[] HeaderImage { get { // Make sure to provide proper frame length for use in the common header image unchecked { CommonHeader.FrameLength = (ushort)BinaryLength; } return CommonHeader.BinaryImage; } } /// /// of string based property names and values for the object. /// public override Dictionary Attributes { get { Dictionary baseAttributes = base.Attributes; CommonHeader.AppendHeaderAttributes(baseAttributes); baseAttributes.Add("64-Bit ID Code", IDCode.ToString()); return baseAttributes; } } #endregion #region [ Methods ] /// /// Parses the binary header image. /// /// Binary image to parse. /// Start index into to begin parsing. /// Length of valid data within . /// The length of the data that was parsed. protected override int ParseHeaderImage(byte[] buffer, int startIndex, int length) { // We already parsed the frame header, so we just skip past it... return CommonFrameHeader.FixedLength; } /// /// Calculates checksum of given . /// /// Buffer image over which to calculate checksum. /// Start index into to calculate checksum. /// Length of data within to calculate checksum. /// Checksum over specified portion of . protected override ushort CalculateChecksum(byte[] buffer, int offset, int length) { // IEEE 1344 uses CRC-CCITT to calculate checksum for frames return buffer.CrcCCITTChecksum(offset, length); } /// /// Populates a with the data needed to serialize the target object. /// /// The to populate with data. /// The destination for this serialization. public override void GetObjectData(SerializationInfo info, StreamingContext context) { base.GetObjectData(info, context); // Serialize data frame info.AddValue("frameHeader", m_frameHeader, typeof(CommonFrameHeader)); } #endregion } }