From b5c6cc567fb017c129fe5642454692b95bd8249f Mon Sep 17 00:00:00 2001 From: Jan Birkmann Date: Mon, 19 Jan 2026 13:10:53 +0100 Subject: [PATCH 1/3] Added EmissionSystemRecord --- CSharpDis7/ElectronicEmissionsPdu.cs | 18 -- CSharpDis7/EmissionSystem.cs | 392 +++++++++++++++++++++++++++ 2 files changed, 392 insertions(+), 18 deletions(-) create mode 100644 CSharpDis7/EmissionSystem.cs diff --git a/CSharpDis7/ElectronicEmissionsPdu.cs b/CSharpDis7/ElectronicEmissionsPdu.cs index 35133a0..3dff67e 100644 --- a/CSharpDis7/ElectronicEmissionsPdu.cs +++ b/CSharpDis7/ElectronicEmissionsPdu.cs @@ -83,25 +83,7 @@ public partial class ElectronicEmissionsPdu : DistributedEmissionsFamilyPdu, IEq /// private ushort _paddingForEmissionsPdu; - /// - /// this field shall specify the length of this emitter system's data in 32-bit words. - /// - private byte _systemDataLength; - - /// - /// the number of beams being described in the current PDU for the emitter system being described. - /// - private byte _numberOfBeams; - /// - /// information about a particular emitter system and shall be represented by an Emitter System record (see 6.2.23). - /// - private EmitterSystem _emitterSystem = new EmitterSystem(); - - /// - /// the location of the antenna beam source with respect to the emitting entity's coordinate system. This location shall be the origin of the emitter coordinate system that shall have the same orientation as the entity coordinate system. This field shall be represented by an Entity Coordinate Vector record see 6.2.95 - /// - private Vector3Float _location = new Vector3Float(); /// /// Electronic emmissions systems THIS IS WRONG. It has the WRONG class type and will cause problems in any marshalling. diff --git a/CSharpDis7/EmissionSystem.cs b/CSharpDis7/EmissionSystem.cs new file mode 100644 index 0000000..77a673b --- /dev/null +++ b/CSharpDis7/EmissionSystem.cs @@ -0,0 +1,392 @@ +// Copyright (c) 1995-2009 held by the author(s). All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the names of the Naval Postgraduate School (NPS) +// Modeling Virtual Environments and Simulation (MOVES) Institute +// (http://www.nps.edu and http://www.MovesInstitute.org) +// nor the names of its contributors may be used to endorse or +// promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008, MOVES Institute, Naval Postgraduate School. All +// rights reserved. This work is licensed under the BSD open source license, +// available at https://www.movesinstitute.org/licenses/bsd.html +// +// Author: DMcG +// Modified for use with C#: +// - Peter Smith (Naval Air Warfare Center - Training Systems Division) +// - Zvonko Bostjancic (Blubit d.o.o. - zvonko.bostjancic@blubit.si) + +using System; +using System.Collections.Generic; +using System.Text; +using System.Diagnostics; +using System.Xml.Serialization; +using DISnet.DataStreamUtilities; +using System.Diagnostics.CodeAnalysis; + +namespace DISnet +{ + /// + /// This field shall specify information about a particular emitter system. Section 6.2.23. + /// + [Serializable] + [XmlRoot] + public partial class EmissionSystem + { + /// + /// this field shall specify the length of this emitter system's data in 32-bit words. + /// + private byte _systemDataLength; + + /// + /// the number of beams being described in the current PDU for the emitter system being described. + /// + private byte _numberOfBeams; + + /// + /// information about a particular emitter system and shall be represented by an Emitter System record (see 6.2.23). + /// + private EmitterSystem _emitterSystem = new EmitterSystem(); + + /// + /// the location of the antenna beam source with respect to the emitting entity's coordinate system. This location shall be the origin of the emitter coordinate system that shall have the same orientation as the entity coordinate system. This field shall be represented by an Entity Coordinate Vector record see 6.2.95 + /// + private Vector3Float _location = new Vector3Float(); + + /// + /// this field shall specify the length of this beam's data (including track/jam information) in 32-bit words. The length shall include the Beam Data Length field. + /// + private byte _beamDataLength; + + /// + /// this field shall specify a unique emitter database number assigned to differentiate between otherwise similar or identical emitter beams within an emitter system. Once established for an exercise, the Beam ID numbers shall not be changed during that exercise. + /// + private byte _beamIdNumber; + + /// + /// this field shall specify a beam parameter index number that shall be used by receiving entities in conjunction with the emitter name field to provide a pointer to the stored database parameters required to regenerate the beam. + /// + private ushort _beamParameterIndex; + + /// + /// The Fundamental Parameter Data Record contains Electromagnetic Emission regeneration parameters that are variable throughout a scenario dependent on the actions of the participants in the simulation. This record also provides basic parametric data that may be used to support low-fidelity simulations which may not have the processing capability to model a high-fidelity regeneration of emission beams. + /// + private EEFundamentalParameterData _fundamentalParameters = new EEFundamentalParameterData(); + + /// + /// this field shall specify the function of a particular beam. + /// + private byte _beamFunction; + + /// + /// this field, in conjunction with the following field, provides a mechanism for an emitter to identify targets that are being illuminated by a track beam or target emitters it is attempting to jam. + /// + private byte _numberOfTargetsInTrackJam; + + /// + /// this field shall specify the function of a particular beam. + /// + private byte _highDensityTrackJam; + + /// + /// this field shall specify the function of a particular beam. + /// + private JammingTechnique _jammingMode; + + /// + /// This field shall identify the targets in an emitter track or emitters a system is attempting to jam. + /// + private TrackJamData[] _trackJam = new TrackJamData[0]; + + /// + /// Initializes a new instance of the class. + /// + public EmissionSystem() + { + } + + /// + /// Implements the operator !=. + /// + /// The left operand. + /// The right operand. + /// + /// true if operands are not equal; otherwise, false. + /// + public static bool operator !=(EmissionSystem left, EmissionSystem right) + { + return !(left == right); + } + + /// + /// Implements the operator ==. + /// + /// The left operand. + /// The right operand. + /// + /// true if both operands are equal; otherwise, false. + /// + public static bool operator ==(EmissionSystem left, EmissionSystem right) + { + if (object.ReferenceEquals(left, right)) + { + return true; + } + + if (((object)left == null) || ((object)right == null)) + { + return false; + } + + return left.Equals(right); + } + + public virtual int GetMarshalledSize() + { + int marshalSize = 0; + + //marshalSize += 2; // this._emitterName + //marshalSize += 1; // this._function + //marshalSize += 1; // this._emitterIdNumber + return marshalSize; + } + + ///// + ///// Gets or sets the Name of the emitter, 16 bit enumeration + ///// + //[XmlElement(Type = typeof(ushort), ElementName = "emitterName")] + //public ushort EmitterName + //{ + // get + // { + // return this._emitterName; + // } + + // set + // { + // this._emitterName = value; + // } + //} + + ///// + ///// Gets or sets the function of the emitter, 8 bit enumeration + ///// + //[XmlElement(Type = typeof(byte), ElementName = "function")] + //public byte Function + //{ + // get + // { + // return this._function; + // } + + // set + // { + // this._function = value; + // } + //} + + ///// + ///// Gets or sets the emitter ID, 8 bit enumeration + ///// + //[XmlElement(Type = typeof(byte), ElementName = "emitterIdNumber")] + //public byte EmitterIdNumber + //{ + // get + // { + // return this._emitterIdNumber; + // } + + // set + // { + // this._emitterIdNumber = value; + // } + //} + + /// + /// Occurs when exception when processing PDU is caught. + /// + public event Action Exception; + + /// + /// Called when exception occurs (raises the event). + /// + /// The exception. + protected void OnException(Exception e) + { + if (this.Exception != null) + { + this.Exception(e); + } + } + + /// + /// Marshal the data to the DataOutputStream. Note: Length needs to be set before calling this method + /// + /// The DataOutputStream instance to which the PDU is marshaled. + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Due to ignoring errors.")] + public virtual void Marshal(DataOutputStream dos) + { + if (dos != null) + { + try + { + //dos.WriteUnsignedShort((ushort)this._emitterName); + //dos.WriteUnsignedByte((byte)this._function); + //dos.WriteUnsignedByte((byte)this._emitterIdNumber); + } + catch (Exception e) + { +#if DEBUG + Trace.WriteLine(e); + Trace.Flush(); +#endif + this.OnException(e); + } + } + } + + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Due to ignoring errors.")] + public virtual void Unmarshal(DataInputStream dis) + { + if (dis != null) + { + try + { + //this._emitterName = dis.ReadUnsignedShort(); + //this._function = dis.ReadUnsignedByte(); + //this._emitterIdNumber = dis.ReadUnsignedByte(); + } + catch (Exception e) + { +#if DEBUG + Trace.WriteLine(e); + Trace.Flush(); +#endif + this.OnException(e); + } + } + } + + /// + /// This allows for a quick display of PDU data. The current format is unacceptable and only used for debugging. + /// This will be modified in the future to provide a better display. Usage: + /// pdu.GetType().InvokeMember("Reflection", System.Reflection.BindingFlags.InvokeMethod, null, pdu, new object[] { sb }); + /// where pdu is an object representing a single pdu and sb is a StringBuilder. + /// Note: The supplied Utilities folder contains a method called 'DecodePDU' in the PDUProcessor Class that provides this functionality + /// + /// The StringBuilder instance to which the PDU is written to. + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Due to ignoring errors.")] + public virtual void Reflection(StringBuilder sb) + { + sb.AppendLine(""); + try + { + //sb.AppendLine("" + this._emitterName.ToString(CultureInfo.InvariantCulture) + ""); + //sb.AppendLine("" + this._function.ToString(CultureInfo.InvariantCulture) + ""); + //sb.AppendLine("" + this._emitterIdNumber.ToString(CultureInfo.InvariantCulture) + ""); + sb.AppendLine(""); + } + catch (Exception e) + { +#if DEBUG + Trace.WriteLine(e); + Trace.Flush(); +#endif + this.OnException(e); + } + } + + /// + /// Determines whether the specified is equal to this instance. + /// + /// The to compare with this instance. + /// + /// true if the specified is equal to this instance; otherwise, false. + /// + public override bool Equals(object obj) + { + return this == obj as EmissionSystem; + } + + /// + /// Compares for reference AND value equality. + /// + /// The object to compare with this instance. + /// + /// true if both operands are equal; otherwise, false. + /// + public bool Equals(EmissionSystem obj) + { + bool ivarsEqual = true; + + if (obj.GetType() != this.GetType()) + { + return false; + } + + //if (this._emitterName != obj._emitterName) + //{ + // ivarsEqual = false; + //} + + //if (this._function != obj._function) + //{ + // ivarsEqual = false; + //} + + //if (this._emitterIdNumber != obj._emitterIdNumber) + //{ + // ivarsEqual = false; + //} + + return ivarsEqual; + } + + /// + /// HashCode Helper + /// + /// The hash value. + /// The new hash value. + private static int GenerateHash(int hash) + { + hash = hash << (5 + hash); + return hash; + } + + /// + /// Gets the hash code. + /// + /// The hash code. + public override int GetHashCode() + { + int result = 0; + + //result = GenerateHash(result) ^ this._emitterName.GetHashCode(); + //result = GenerateHash(result) ^ this._function.GetHashCode(); + //result = GenerateHash(result) ^ this._emitterIdNumber.GetHashCode(); + + return result; + } + } +} From 949390008582cb5344493dd33ea7af056fd76788 Mon Sep 17 00:00:00 2001 From: Jan Birkmann Date: Thu, 22 Jan 2026 12:37:41 +0100 Subject: [PATCH 2/3] Refactor DIS Electronic Emissions PDU and related classes Refactored ElectronicEmissionsPdu, EmissionSystem, and related classes to accurately implement the DIS 7.0.5 standard. Added a new Beam class, replaced incorrect system/beam structures with proper lists, and updated marshalling, reflection, and equality logic. Standardized namespaces, improved XML serialization, and cleaned up legacy code for correctness and maintainability. --- CSharpDis7/Beam.cs | 607 +++++++++++++++++++++++++++ CSharpDis7/ElectronicEmissionsPdu.cs | 174 ++------ CSharpDis7/EmissionSystem.cs | 387 ++++++++++------- 3 files changed, 883 insertions(+), 285 deletions(-) create mode 100644 CSharpDis7/Beam.cs diff --git a/CSharpDis7/Beam.cs b/CSharpDis7/Beam.cs new file mode 100644 index 0000000..1b26ac7 --- /dev/null +++ b/CSharpDis7/Beam.cs @@ -0,0 +1,607 @@ +// Copyright (c) 1995-2009 held by the author(s). All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the names of the Naval Postgraduate School (NPS) +// Modeling Virtual Environments and Simulation (MOVES) Institute +// (http://www.nps.edu and http://www.MovesInstitute.org) +// nor the names of its contributors may be used to endorse or +// promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008, MOVES Institute, Naval Postgraduate School. All +// rights reserved. This work is licensed under the BSD open source license, +// available at https://www.movesinstitute.org/licenses/bsd.html +// +// Author: DMcG +// Modified for use with C#: +// - Peter Smith (Naval Air Warfare Center - Training Systems Division) +// - Zvonko Bostjancic (Blubit d.o.o. - zvonko.bostjancic@blubit.si) + +using System; +using System.Collections.Generic; +using System.Text; +using System.Diagnostics; +using System.Xml.Serialization; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using OpenDis.Core; + +namespace OpenDis.Dis2012 +{ + /// + /// Describes the scan volue of an emitter beam. Section 6.2.13. + /// + [Serializable] + [XmlRoot] + public partial class Beam + { + /// + /// this field shall specify the length of this beam's data (including track/jam information) in 32-bit words. The length shall include the Beam Data Length field. + /// + private byte _beamDataLength; + + /// + /// this field shall specify a unique emitter database number assigned to differentiate between otherwise similar or identical emitter beams within an emitter system. Once established for an exercise, the Beam ID numbers shall not be changed during that exercise. + /// + private byte _beamIdNumber; + + /// + /// this field shall specify a beam parameter index number that shall be used by receiving entities in conjunction with the emitter name field to provide a pointer to the stored database parameters required to regenerate the beam. + /// + private ushort _beamParameterIndex; + + /// + /// The Fundamental Parameter Data Record contains Electromagnetic Emission regeneration parameters that are variable throughout a scenario dependent on the actions of the participants in the simulation. This record also provides basic parametric data that may be used to support low-fidelity simulations which may not have the processing capability to model a high-fidelity regeneration of emission beams. + /// + private EEFundamentalParameterData _fundamentalParameters = new EEFundamentalParameterData(); + + /// + /// Beam scan volume data (azimuth/elevation centers and sweeps, sweep sync) + /// + private BeamData _beamData = new BeamData(); + + /// + /// this field shall specify the function of a particular beam. + /// + private byte _beamFunction; + + /// + /// this field, in conjunction with the following field, provides a mechanism for an emitter to identify targets that are being illuminated by a track beam or target emitters it is attempting to jam. + /// + private byte _numberOfTargetsInTrackJam; + + /// + /// this field shall specify the function of a particular beam. + /// + private byte _highDensityTrackJam; + + /// + /// padding + /// + private byte _paddingForEmissionSystem2; + + /// + /// this field shall specify the function of a particular beam. + /// + private JammingTechnique _jammingTechnique = new JammingTechnique(); + + /// + /// This field shall identify the targets in an emitter track or emitters a system is attempting to jam. + /// + private List _trackJamData = new List(); + + /// + /// Initializes a new instance of the class. + /// + public Beam() + { + } + + /// + /// Implements the operator !=. + /// + /// The left operand. + /// The right operand. + /// + /// true if operands are not equal; otherwise, false. + /// + public static bool operator !=(Beam left, Beam right) + { + return !(left == right); + } + + /// + /// Implements the operator ==. + /// + /// The left operand. + /// The right operand. + /// + /// true if both operands are equal; otherwise, false. + /// + public static bool operator ==(Beam left, Beam right) + { + if (object.ReferenceEquals(left, right)) + return true; + + if ((object)left == null || (object)right == null) + return false; + + return left.Equals(right); + } + + public virtual int GetMarshalledSize() + { + int marshalSize = 0; + + marshalSize += 1; // _beamDataLength + marshalSize += 1; // _beamIdNumber + marshalSize += 2; // _beamParameterIndex + marshalSize += this._fundamentalParameters.GetMarshalledSize(); + marshalSize += this._beamData.GetMarshalledSize(); + marshalSize += 1; // _beamFunction + marshalSize += 1; // _numberOfTargetsInTrackJam + marshalSize += 1; // _highDensityTrackJam + marshalSize += 1; // _paddingForEmissionSystem2 + marshalSize += this._jammingTechnique.GetMarshalledSize(); + + for (int idx = 0; idx < this._trackJamData.Count; idx++) + { + marshalSize += this._trackJamData[idx].GetMarshalledSize(); + } + + return marshalSize; + } + + /// + /// this field shall specify the length of this beam's data (including track/jam information) in 32-bit words. The length shall include the Beam Data Length field. + /// + [XmlElement(Type = typeof(byte), ElementName = "beamDataLength")] + public byte BeamDataLength + { + get + { + return this._beamDataLength; + } + + set + { + this._beamDataLength = value; + } + } + + /// + /// this field shall specify a unique emitter database number assigned to differentiate between otherwise similar or identical emitter beams within an emitter system. Once established for an exercise, the Beam ID numbers shall not be changed during that exercise. + /// + [XmlElement(Type = typeof(byte), ElementName = "beamIdNumber")] + public byte BeamIdNumber + { + get + { + return this._beamIdNumber; + } + + set + { + this._beamIdNumber = value; + } + } + + /// + /// this field shall specify a beam parameter index number that shall be used by receiving entities in conjunction with the emitter name field to provide a pointer to the stored database parameters required to regenerate the beam. + /// + [XmlElement(Type = typeof(ushort), ElementName = "beamParameterIndex")] + public ushort BeamParameterIndex + { + get + { + return this._beamParameterIndex; + } + + set + { + this._beamParameterIndex = value; + } + } + + /// + /// this field shall specify dynamic parameters of the emitter. + /// + [XmlElement(Type = typeof(EEFundamentalParameterData), ElementName = "fundamentalParameters")] + public EEFundamentalParameterData FundamentalParameters + { + get + { + return this._fundamentalParameters; + } + + set + { + this._fundamentalParameters = value; + } + } + + /// + /// Beam scan volume data (azimuth/elevation centers and sweeps, sweep sync) + /// + [XmlElement(Type = typeof(BeamData), ElementName = "beamData")] + public BeamData BeamData + { + get + { + return this._beamData; + } + + set + { + this._beamData = value; + } + } + + /// + /// this field shall specify the function of a particular beam. + /// + [XmlElement(Type = typeof(byte), ElementName = "beamFunction")] + public byte BeamFunction + { + get + { + return this._beamFunction; + } + + set + { + this._beamFunction = value; + } + } + + /// + /// This field, in conjunction with the following field, provides a mechanism for an emitter to identify targets that are being illuminated by a track beam or target emitters it is attempting to jam. + /// + [XmlElement(Type = typeof(byte), ElementName = "numberOfTargetsInTrackJam")] + public byte NumberOfTargetsInTrackJam + { + get + { + return this._numberOfTargetsInTrackJam; + } + + set + { + this._numberOfTargetsInTrackJam = value; + } + } + + /// + /// This field shall be used to indicate whether or not the receiving simulation applications can assume that all targets, in the scan pattern which the sending emitter can track (for a phased array system) or jam (for a jamming system), are being tracked or jammed respectively. + /// + [XmlElement(Type = typeof(byte), ElementName = "highDensityTrackJam")] + public byte HighDensityTrackJam + { + get + { + return this._highDensityTrackJam; + } + + set + { + this._highDensityTrackJam = value; + } + } + + /// + /// padding + /// + [XmlElement(Type = typeof(byte), ElementName = "paddingForEmissionSystem2")] + public byte PaddingForEmissionSystem2 + { + get + { + return this._paddingForEmissionSystem2; + } + + set + { + this._paddingForEmissionSystem2 = value; + } + } + + /// + /// this field shall be used to identify one or multiple jamming techniques being applied. + /// + [XmlElement(Type = typeof(JammingTechnique), ElementName = "jammingTechnique")] + public JammingTechnique JammingTechnique + { + get + { + return this._jammingTechnique; + } + + set + { + this._jammingTechnique = value; + } + } + + /// + /// this field shall identify the targets in an emitter track or emitters a system is attempting to jam. + /// + [XmlElement(ElementName = "trackJamDataList")] + public List TrackJamData + { + get + { + return this._trackJamData; + } + + set + { + this._trackJamData = value; + } + } + + /// + /// Occurs when exception when processing PDU is caught. + /// + public event Action Exception; + + /// + /// Called when exception occurs (raises the event). + /// + /// The exception. + protected void OnException(Exception e) + { + if (this.Exception != null) + this.Exception(e); + } + + /// + /// Marshal the data to the DataOutputStream. Note: Length needs to be set before calling this method + /// + /// The DataOutputStream instance to which the PDU is marshaled. + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Due to ignoring errors.")] + public virtual void Marshal(DataOutputStream dos) + { + if (dos == null) return; + + try + { + dos.WriteUnsignedByte(this._beamDataLength); + dos.WriteUnsignedByte(this._beamIdNumber); + dos.WriteUnsignedShort(this._beamParameterIndex); + + this._fundamentalParameters.Marshal(dos); + this._beamData.Marshal(dos); + + dos.WriteUnsignedByte(this._beamFunction); + dos.WriteUnsignedByte(this._numberOfTargetsInTrackJam); + dos.WriteUnsignedByte(this._highDensityTrackJam); + dos.WriteUnsignedByte(this._paddingForEmissionSystem2); + + this._jammingTechnique.Marshal(dos); + + for (int i = 0; i < this._numberOfTargetsInTrackJam; i++) + { + this._trackJamData[i].Marshal(dos); + } + } + catch (Exception e) + { +#if DEBUG + Trace.WriteLine(e); + Trace.Flush(); +#endif + this.OnException(e); + } + } + + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Due to ignoring errors.")] + public virtual void Unmarshal(DataInputStream dis) + { + if (dis == null) return; + + try + { + this._beamDataLength = dis.ReadUnsignedByte(); + this._beamIdNumber = dis.ReadUnsignedByte(); + this._beamParameterIndex = dis.ReadUnsignedShort(); + + this._fundamentalParameters.Unmarshal(dis); + this._beamData.Unmarshal(dis); + + this._beamFunction = dis.ReadUnsignedByte(); + this._numberOfTargetsInTrackJam = dis.ReadUnsignedByte(); + this._highDensityTrackJam = dis.ReadUnsignedByte(); + this._paddingForEmissionSystem2 = dis.ReadUnsignedByte(); + + this._jammingTechnique.Unmarshal(dis); + + this._trackJamData.Clear(); + for (int i = 0; i < this._numberOfTargetsInTrackJam; i++) + { + TrackJamData tjd = new TrackJamData(); + tjd.Unmarshal(dis); + this._trackJamData.Add(tjd); + } + } + catch (Exception e) + { +#if DEBUG + Trace.WriteLine(e); + Trace.Flush(); +#endif + this.OnException(e); + } + } + + /// + /// This allows for a quick display of PDU data. The current format is unacceptable and only used for debugging. + /// This will be modified in the future to provide a better display. Usage: + /// pdu.GetType().InvokeMember("Reflection", System.Reflection.BindingFlags.InvokeMethod, null, pdu, new object[] { sb }); + /// where pdu is an object representing a single pdu and sb is a StringBuilder. + /// Note: The supplied Utilities folder contains a method called 'DecodePDU' in the PDUProcessor Class that provides this functionality + /// + /// The StringBuilder instance to which the PDU is written to. + public virtual void Reflection(StringBuilder sb) + { + sb.AppendLine(""); + try + { + sb.AppendLine("" + this._beamDataLength + ""); + sb.AppendLine("" + this._beamIdNumber + ""); + sb.AppendLine("" + this._beamParameterIndex + ""); + + sb.AppendLine(""); + this._fundamentalParameters.Reflection(sb); + sb.AppendLine(""); + + sb.AppendLine(""); + this._beamData.Reflection(sb); + sb.AppendLine(""); + + sb.AppendLine("" + this._beamFunction + ""); + sb.AppendLine("" + this._numberOfTargetsInTrackJam + ""); + sb.AppendLine("" + this._highDensityTrackJam + ""); + sb.AppendLine("" + this._paddingForEmissionSystem2 + ""); + + sb.AppendLine(""); + this._jammingTechnique.Reflection(sb); + sb.AppendLine(""); + + sb.AppendLine(""); + for (int idx = 0; idx < this._trackJamData.Count; idx++) + { + sb.AppendLine(""); + this._trackJamData[idx].Reflection(sb); + sb.AppendLine(""); + } + sb.AppendLine(""); + } + catch (Exception e) + { +#if DEBUG + Trace.WriteLine(e); + Trace.Flush(); +#endif + this.OnException(e); + } + + sb.AppendLine(""); + } + + /// + /// Determines whether the specified is equal to this instance. + /// + /// The to compare with this instance. + /// + /// true if the specified is equal to this instance; otherwise, false. + /// + public override bool Equals(object obj) + { + return this == obj as Beam; + } + + /// + /// Compares for reference AND value equality. + /// + /// The object to compare with this instance. + /// + /// true if both operands are equal; otherwise, false. + /// + public bool Equals(Beam obj) + { + if (obj == null) + return false; + + if (obj.GetType() != this.GetType()) + return false; + + bool ivarsEqual = true; + + if (this._beamDataLength != obj._beamDataLength) ivarsEqual = false; + if (this._beamIdNumber != obj._beamIdNumber) ivarsEqual = false; + if (this._beamParameterIndex != obj._beamParameterIndex) ivarsEqual = false; + + if (!this._fundamentalParameters.Equals(obj._fundamentalParameters)) ivarsEqual = false; + if (!this._beamData.Equals(obj._beamData)) ivarsEqual = false; + + if (this._beamFunction != obj._beamFunction) ivarsEqual = false; + if (this._numberOfTargetsInTrackJam != obj._numberOfTargetsInTrackJam) ivarsEqual = false; + if (this._highDensityTrackJam != obj._highDensityTrackJam) ivarsEqual = false; + if (this._paddingForEmissionSystem2 != obj._paddingForEmissionSystem2) ivarsEqual = false; + + if (!this._jammingTechnique.Equals(obj._jammingTechnique)) ivarsEqual = false; + + if (this._trackJamData.Count != obj._trackJamData.Count) ivarsEqual = false; + else + { + for (int idx = 0; idx < this._trackJamData.Count; idx++) + { + if (!this._trackJamData[idx].Equals(obj._trackJamData[idx])) ivarsEqual = false; + } + } + + return ivarsEqual; + } + + /// + /// HashCode Helper + /// + /// The hash value. + /// The new hash value. + private static int GenerateHash(int hash) + { + hash = hash << (5 + hash); + return hash; + } + + /// + /// Gets the hash code. + /// + /// The hash code. + public override int GetHashCode() + { + int result = 0; + + result = GenerateHash(result) ^ this._beamDataLength.GetHashCode(); + result = GenerateHash(result) ^ this._beamIdNumber.GetHashCode(); + result = GenerateHash(result) ^ this._beamParameterIndex.GetHashCode(); + + if (this._fundamentalParameters != null) result = GenerateHash(result) ^ this._fundamentalParameters.GetHashCode(); + if (this._beamData != null) result = GenerateHash(result) ^ this._beamData.GetHashCode(); + + result = GenerateHash(result) ^ this._beamFunction.GetHashCode(); + result = GenerateHash(result) ^ this._numberOfTargetsInTrackJam.GetHashCode(); + result = GenerateHash(result) ^ this._highDensityTrackJam.GetHashCode(); + result = GenerateHash(result) ^ this._paddingForEmissionSystem2.GetHashCode(); + + if (this._jammingTechnique != null) result = GenerateHash(result) ^ this._jammingTechnique.GetHashCode(); + + for (int idx = 0; idx < this._trackJamData.Count; idx++) + { + if (this._trackJamData[idx] != null) result = GenerateHash(result) ^ this._trackJamData[idx].GetHashCode(); + } + + return result; + } + } +} diff --git a/CSharpDis7/ElectronicEmissionsPdu.cs b/CSharpDis7/ElectronicEmissionsPdu.cs index 3dff67e..0ec6eea 100644 --- a/CSharpDis7/ElectronicEmissionsPdu.cs +++ b/CSharpDis7/ElectronicEmissionsPdu.cs @@ -36,6 +36,7 @@ // Modified for use with C#: // - Peter Smith (Naval Air Warfare Center - Training Systems Division) // - Zvonko Bostjancic (Blubit d.o.o. - zvonko.bostjancic@blubit.si) +// - Jan Birkmann (ELT Group Germany) using System; using System.Collections.Generic; @@ -56,6 +57,7 @@ namespace DISnet [XmlInclude(typeof(EmitterSystem))] [XmlInclude(typeof(Vector3Float))] [XmlInclude(typeof(Vector3Float))] + [XmlInclude(typeof(EmissionSystem))] public partial class ElectronicEmissionsPdu : DistributedEmissionsFamilyPdu, IEquatable { /// @@ -83,12 +85,10 @@ public partial class ElectronicEmissionsPdu : DistributedEmissionsFamilyPdu, IEq /// private ushort _paddingForEmissionsPdu; - - /// - /// Electronic emmissions systems THIS IS WRONG. It has the WRONG class type and will cause problems in any marshalling. + /// Information about a particular emitter system /// - private List _systems = new List(); + private List _emissionSystems = new List(); /// /// Initializes a new instance of the class. @@ -136,7 +136,7 @@ public ElectronicEmissionsPdu() public override int GetMarshalledSize() { - int marshalSize = 0; + int marshalSize = 0; marshalSize = base.GetMarshalledSize(); marshalSize += this._emittingEntityID.GetMarshalledSize(); // this._emittingEntityID @@ -144,13 +144,9 @@ public override int GetMarshalledSize() marshalSize += 1; // this._stateUpdateIndicator marshalSize += 1; // this._numberOfSystems marshalSize += 2; // this._paddingForEmissionsPdu - marshalSize += 1; // this._systemDataLength - marshalSize += 1; // this._numberOfBeams - marshalSize += this._emitterSystem.GetMarshalledSize(); // this._emitterSystem - marshalSize += this._location.GetMarshalledSize(); // this._location - for (int idx = 0; idx < this._systems.Count; idx++) + for (int idx = 0; idx < this._numberOfSystems; idx++) { - Vector3Float listElement = (Vector3Float)this._systems[idx]; + EmissionSystem listElement = this._emissionSystems[idx]; marshalSize += listElement.GetMarshalledSize(); } @@ -245,82 +241,19 @@ public ushort PaddingForEmissionsPdu } /// - /// Gets or sets the this field shall specify the length of this emitter system's data in 32-bit words. - /// - [XmlElement(Type = typeof(byte), ElementName = "systemDataLength")] - public byte SystemDataLength - { - get - { - return this._systemDataLength; - } - - set - { - this._systemDataLength = value; - } - } - - /// - /// Gets or sets the the number of beams being described in the current PDU for the emitter system being described. - /// - [XmlElement(Type = typeof(byte), ElementName = "numberOfBeams")] - public byte NumberOfBeams - { - get - { - return this._numberOfBeams; - } - - set - { - this._numberOfBeams = value; - } - } - - /// - /// Gets or sets the information about a particular emitter system and shall be represented by an Emitter System record (see 6.2.23). - /// - [XmlElement(Type = typeof(EmitterSystem), ElementName = "emitterSystem")] - public EmitterSystem EmitterSystem - { - get - { - return this._emitterSystem; - } - - set - { - this._emitterSystem = value; - } - } - - /// - /// Gets or sets the the location of the antenna beam source with respect to the emitting entity's coordinate system. This location shall be the origin of the emitter coordinate system that shall have the same orientation as the entity coordinate system. This field shall be represented by an Entity Coordinate Vector record see 6.2.95 + /// Gets or sets the Electronic emmissions systems /// - [XmlElement(Type = typeof(Vector3Float), ElementName = "location")] - public Vector3Float Location + [XmlElement(ElementName = "emissionSystemList", Type = typeof(List))] + public List EmissionSystems { get { - return this._location; + return this._emissionSystems; } set { - this._location = value; - } - } - - /// - /// Gets or sets the Electronic emmissions systems THIS IS WRONG. It has the WRONG class type and will cause problems in any marshalling. - /// - [XmlElement(ElementName = "systemsList", Type = typeof(List))] - public List Systems - { - get - { - return this._systems; + this._emissionSystems = value; } } @@ -350,17 +283,13 @@ public override void Marshal(DataOutputStream dos) this._emittingEntityID.Marshal(dos); this._eventID.Marshal(dos); dos.WriteUnsignedByte((byte)this._stateUpdateIndicator); - dos.WriteUnsignedByte((byte)this._systems.Count); + dos.WriteUnsignedByte((byte)this._numberOfSystems); dos.WriteUnsignedShort((ushort)this._paddingForEmissionsPdu); - dos.WriteUnsignedByte((byte)this._systemDataLength); - dos.WriteUnsignedByte((byte)this._numberOfBeams); - this._emitterSystem.Marshal(dos); - this._location.Marshal(dos); - for (int idx = 0; idx < this._systems.Count; idx++) + for (int idx = 0; idx < this._numberOfSystems; idx++) { - Vector3Float aVector3Float = (Vector3Float)this._systems[idx]; - aVector3Float.Marshal(dos); + EmissionSystem system = this._emissionSystems[idx]; + system.Marshal(dos); } } catch (Exception e) @@ -388,16 +317,13 @@ public override void Unmarshal(DataInputStream dis) this._stateUpdateIndicator = dis.ReadUnsignedByte(); this._numberOfSystems = dis.ReadUnsignedByte(); this._paddingForEmissionsPdu = dis.ReadUnsignedShort(); - this._systemDataLength = dis.ReadUnsignedByte(); - this._numberOfBeams = dis.ReadUnsignedByte(); - this._emitterSystem.Unmarshal(dis); - this._location.Unmarshal(dis); for (int idx = 0; idx < this.NumberOfSystems; idx++) { - Vector3Float anX = new Vector3Float(); - anX.Unmarshal(dis); - this._systems.Add(anX); - }; + EmissionSystem system = new EmissionSystem(); + system.Unmarshal(dis); + this._emissionSystems.Add(system); + } + ; } catch (Exception e) @@ -433,22 +359,14 @@ public override void Reflection(StringBuilder sb) this._eventID.Reflection(sb); sb.AppendLine(""); sb.AppendLine("" + this._stateUpdateIndicator.ToString(CultureInfo.InvariantCulture) + ""); - sb.AppendLine("" + this._systems.Count.ToString(CultureInfo.InvariantCulture) + ""); + sb.AppendLine("" + this._numberOfSystems.ToString(CultureInfo.InvariantCulture) + ""); sb.AppendLine("" + this._paddingForEmissionsPdu.ToString(CultureInfo.InvariantCulture) + ""); - sb.AppendLine("" + this._systemDataLength.ToString(CultureInfo.InvariantCulture) + ""); - sb.AppendLine("" + this._numberOfBeams.ToString(CultureInfo.InvariantCulture) + ""); - sb.AppendLine(""); - this._emitterSystem.Reflection(sb); - sb.AppendLine(""); - sb.AppendLine(""); - this._location.Reflection(sb); - sb.AppendLine(""); - for (int idx = 0; idx < this._systems.Count; idx++) + for (int idx = 0; idx < this._emissionSystems.Count; idx++) { - sb.AppendLine(""); - Vector3Float aVector3Float = (Vector3Float)this._systems[idx]; - aVector3Float.Reflection(sb); - sb.AppendLine(""); + sb.AppendLine(""); + EmissionSystem system = this._emissionSystems[idx]; + system.Reflection(sb); + sb.AppendLine(""); } sb.AppendLine(""); @@ -459,7 +377,7 @@ public override void Reflection(StringBuilder sb) Trace.WriteLine(e); Trace.Flush(); #endif - this.OnException(e); + this.OnException(e); } } @@ -518,36 +436,16 @@ public bool Equals(ElectronicEmissionsPdu obj) ivarsEqual = false; } - if (this._systemDataLength != obj._systemDataLength) - { - ivarsEqual = false; - } - - if (this._numberOfBeams != obj._numberOfBeams) - { - ivarsEqual = false; - } - - if (!this._emitterSystem.Equals(obj._emitterSystem)) - { - ivarsEqual = false; - } - - if (!this._location.Equals(obj._location)) - { - ivarsEqual = false; - } - - if (this._systems.Count != obj._systems.Count) + if (this._emissionSystems.Count != obj._emissionSystems.Count) { ivarsEqual = false; } if (ivarsEqual) { - for (int idx = 0; idx < this._systems.Count; idx++) + for (int idx = 0; idx < this._emissionSystems.Count; idx++) { - if (!this._systems[idx].Equals(obj._systems[idx])) + if (!this._emissionSystems[idx].Equals(obj._emissionSystems[idx])) { ivarsEqual = false; } @@ -583,16 +481,12 @@ public override int GetHashCode() result = GenerateHash(result) ^ this._stateUpdateIndicator.GetHashCode(); result = GenerateHash(result) ^ this._numberOfSystems.GetHashCode(); result = GenerateHash(result) ^ this._paddingForEmissionsPdu.GetHashCode(); - result = GenerateHash(result) ^ this._systemDataLength.GetHashCode(); - result = GenerateHash(result) ^ this._numberOfBeams.GetHashCode(); - result = GenerateHash(result) ^ this._emitterSystem.GetHashCode(); - result = GenerateHash(result) ^ this._location.GetHashCode(); - if (this._systems.Count > 0) + if (this._numberOfSystems > 0) { - for (int idx = 0; idx < this._systems.Count; idx++) + for (int idx = 0; idx < this._numberOfSystems; idx++) { - result = GenerateHash(result) ^ this._systems[idx].GetHashCode(); + result = GenerateHash(result) ^ this._emissionSystems[idx].GetHashCode(); } } diff --git a/CSharpDis7/EmissionSystem.cs b/CSharpDis7/EmissionSystem.cs index 77a673b..780afbc 100644 --- a/CSharpDis7/EmissionSystem.cs +++ b/CSharpDis7/EmissionSystem.cs @@ -32,18 +32,17 @@ // rights reserved. This work is licensed under the BSD open source license, // available at https://www.movesinstitute.org/licenses/bsd.html // -// Author: DMcG +// Author: werbaer-bot // Modified for use with C#: -// - Peter Smith (Naval Air Warfare Center - Training Systems Division) -// - Zvonko Bostjancic (Blubit d.o.o. - zvonko.bostjancic@blubit.si) +// - Jan Birkmann (ELT Group Germany) using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using System.Xml.Serialization; -using DISnet.DataStreamUtilities; using System.Diagnostics.CodeAnalysis; +using OpenDis.Core; namespace DISnet { @@ -52,10 +51,14 @@ namespace DISnet /// [Serializable] [XmlRoot] + [XmlInclude(typeof(EmitterSystem))] + [XmlInclude(typeof(Vector3Float))] + [XmlInclude(typeof(Beam))] + public partial class EmissionSystem { /// - /// this field shall specify the length of this emitter system's data in 32-bit words. + /// this field shall specify the length of this emitter system's data in 32-bit words. /// private byte _systemDataLength; @@ -64,6 +67,11 @@ public partial class EmissionSystem /// private byte _numberOfBeams; + /// + /// padding + /// + private ushort _paddingForEmissionSystem1; + /// /// information about a particular emitter system and shall be represented by an Emitter System record (see 6.2.23). /// @@ -75,49 +83,9 @@ public partial class EmissionSystem private Vector3Float _location = new Vector3Float(); /// - /// this field shall specify the length of this beam's data (including track/jam information) in 32-bit words. The length shall include the Beam Data Length field. - /// - private byte _beamDataLength; - - /// - /// this field shall specify a unique emitter database number assigned to differentiate between otherwise similar or identical emitter beams within an emitter system. Once established for an exercise, the Beam ID numbers shall not be changed during that exercise. - /// - private byte _beamIdNumber; - - /// - /// this field shall specify a beam parameter index number that shall be used by receiving entities in conjunction with the emitter name field to provide a pointer to the stored database parameters required to regenerate the beam. - /// - private ushort _beamParameterIndex; - - /// - /// The Fundamental Parameter Data Record contains Electromagnetic Emission regeneration parameters that are variable throughout a scenario dependent on the actions of the participants in the simulation. This record also provides basic parametric data that may be used to support low-fidelity simulations which may not have the processing capability to model a high-fidelity regeneration of emission beams. - /// - private EEFundamentalParameterData _fundamentalParameters = new EEFundamentalParameterData(); - - /// - /// this field shall specify the function of a particular beam. - /// - private byte _beamFunction; - - /// - /// this field, in conjunction with the following field, provides a mechanism for an emitter to identify targets that are being illuminated by a track beam or target emitters it is attempting to jam. - /// - private byte _numberOfTargetsInTrackJam; - - /// - /// this field shall specify the function of a particular beam. - /// - private byte _highDensityTrackJam; - - /// - /// this field shall specify the function of a particular beam. - /// - private JammingTechnique _jammingMode; - - /// - /// This field shall identify the targets in an emitter track or emitters a system is attempting to jam. + /// list of Beams /// - private TrackJamData[] _trackJam = new TrackJamData[0]; + private List _beams = new List(); /// /// Initializes a new instance of the class. @@ -164,64 +132,106 @@ public EmissionSystem() public virtual int GetMarshalledSize() { - int marshalSize = 0; + int marshalSize = 0; + + marshalSize += 1; // this._systemDataLength + marshalSize += 1; // this._numberOfBeams + marshalSize += 2; // this._paddingForEmissionSystem1 + marshalSize += this._emitterSystem.GetMarshalledSize(); + marshalSize += this._location.GetMarshalledSize(); + + for (int idx = 0; idx < this._beams.Count; idx++) + { + marshalSize += this._beams[idx].GetMarshalledSize(); + } - //marshalSize += 2; // this._emitterName - //marshalSize += 1; // this._function - //marshalSize += 1; // this._emitterIdNumber return marshalSize; } - ///// - ///// Gets or sets the Name of the emitter, 16 bit enumeration - ///// - //[XmlElement(Type = typeof(ushort), ElementName = "emitterName")] - //public ushort EmitterName - //{ - // get - // { - // return this._emitterName; - // } - - // set - // { - // this._emitterName = value; - // } - //} - - ///// - ///// Gets or sets the function of the emitter, 8 bit enumeration - ///// - //[XmlElement(Type = typeof(byte), ElementName = "function")] - //public byte Function - //{ - // get - // { - // return this._function; - // } - - // set - // { - // this._function = value; - // } - //} - - ///// - ///// Gets or sets the emitter ID, 8 bit enumeration - ///// - //[XmlElement(Type = typeof(byte), ElementName = "emitterIdNumber")] - //public byte EmitterIdNumber - //{ - // get - // { - // return this._emitterIdNumber; - // } - - // set - // { - // this._emitterIdNumber = value; - // } - //} + /// + /// this field shall specify the length of this emitter system's data in 32-bit words. + /// + [XmlElement(Type = typeof(byte), ElementName = "systemDataLength")] + public byte SystemDataLength + { + get + { + return this._systemDataLength; + } + + set + { + this._systemDataLength = value; + } + } + + /// + /// this field shall specify the number of beams being described in the current PDU for the system being described. + /// + [XmlElement(Type = typeof(byte), ElementName = "numberOfBeams")] + public byte NumberOfBeams + { + get + { + return this._numberOfBeams; + } + + set + { + this._numberOfBeams = value; + } + } + + /// + /// this field shall specify information about a particular emitter system. + /// + [XmlElement(Type = typeof(EmitterSystem), ElementName = "emitterSystem")] + public EmitterSystem EmitterSystem + { + get + { + return this._emitterSystem; + } + + set + { + this._emitterSystem = value; + } + } + + /// + /// this field shall specify the location of the antenna beam source with respect to the emitting entity's coordinate system. This location shall be the origin of the emitter coordinate system which shall be parallel to the entity coordinate system. + /// + [XmlElement(Type = typeof(Vector3Float), ElementName = "location")] + public Vector3Float Location + { + get + { + return this._location; + } + + set + { + this._location = value; + } + } + + /// + /// list of Beams + /// + [XmlElement(ElementName = "beams")] + public List Beams + { + get + { + return this._beams; + } + + set + { + this._beams = value; + } + } /// /// Occurs when exception when processing PDU is caught. @@ -247,47 +257,65 @@ protected void OnException(Exception e) [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Due to ignoring errors.")] public virtual void Marshal(DataOutputStream dos) { - if (dos != null) + if (dos == null) return; + + try { - try + dos.WriteUnsignedByte(this._systemDataLength); + dos.WriteUnsignedByte(this._numberOfBeams); + dos.WriteUnsignedShort(this._paddingForEmissionSystem1); + + this._emitterSystem.Marshal(dos); + this._location.Marshal(dos); + + for (int i = 0; i < this._beams.Count; i++) { - //dos.WriteUnsignedShort((ushort)this._emitterName); - //dos.WriteUnsignedByte((byte)this._function); - //dos.WriteUnsignedByte((byte)this._emitterIdNumber); + this._beams[i].Marshal(dos); } - catch (Exception e) - { + } + catch (Exception e) + { #if DEBUG - Trace.WriteLine(e); - Trace.Flush(); + Trace.WriteLine(e); + Trace.Flush(); #endif - this.OnException(e); - } + this.OnException(e); } } [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Due to ignoring errors.")] public virtual void Unmarshal(DataInputStream dis) { - if (dis != null) + if (dis == null) return; + + try { - try + this._systemDataLength = dis.ReadUnsignedByte(); + this._numberOfBeams = dis.ReadUnsignedByte(); + this._paddingForEmissionSystem1 = dis.ReadUnsignedShort(); + + this._emitterSystem.Unmarshal(dis); + this._location.Unmarshal(dis); + + this._beams.Clear(); + for (int i = 0; i < this._numberOfBeams; i++) { - //this._emitterName = dis.ReadUnsignedShort(); - //this._function = dis.ReadUnsignedByte(); - //this._emitterIdNumber = dis.ReadUnsignedByte(); + Beam b = new Beam(); + b.Unmarshal(dis); + this._beams.Add(b); } - catch (Exception e) - { + } + catch (Exception e) + { #if DEBUG - Trace.WriteLine(e); - Trace.Flush(); + Trace.WriteLine(e); + Trace.Flush(); #endif - this.OnException(e); - } + this.OnException(e); } } + /// /// This allows for a quick display of PDU data. The current format is unacceptable and only used for debugging. /// This will be modified in the future to provide a better display. Usage: @@ -302,21 +330,40 @@ public virtual void Reflection(StringBuilder sb) sb.AppendLine(""); try { - //sb.AppendLine("" + this._emitterName.ToString(CultureInfo.InvariantCulture) + ""); - //sb.AppendLine("" + this._function.ToString(CultureInfo.InvariantCulture) + ""); - //sb.AppendLine("" + this._emitterIdNumber.ToString(CultureInfo.InvariantCulture) + ""); - sb.AppendLine(""); + sb.AppendLine("" + this._systemDataLength + ""); + sb.AppendLine("" + this._numberOfBeams + ""); + sb.AppendLine("" + this._paddingForEmissionSystem1 + ""); + + sb.AppendLine(""); + this._emitterSystem.Reflection(sb); + sb.AppendLine(""); + + sb.AppendLine(""); + this._location.Reflection(sb); + sb.AppendLine(""); + + sb.AppendLine(""); + for (int idx = 0; idx < this._beams.Count; idx++) + { + sb.AppendLine(""); + this._beams[idx].Reflection(sb); + sb.AppendLine(""); + } + sb.AppendLine(""); } catch (Exception e) { #if DEBUG - Trace.WriteLine(e); - Trace.Flush(); + Trace.WriteLine(e); + Trace.Flush(); #endif - this.OnException(e); + this.OnException(e); } + + sb.AppendLine(""); } + /// /// Determines whether the specified is equal to this instance. /// @@ -340,29 +387,60 @@ public bool Equals(EmissionSystem obj) { bool ivarsEqual = true; + if (obj == null) + { + return false; + } + if (obj.GetType() != this.GetType()) { return false; } - //if (this._emitterName != obj._emitterName) - //{ - // ivarsEqual = false; - //} + if (this._systemDataLength != obj._systemDataLength) + { + ivarsEqual = false; + } + + if (this._numberOfBeams != obj._numberOfBeams) + { + ivarsEqual = false; + } + + if (this._paddingForEmissionSystem1 != obj._paddingForEmissionSystem1) + { + ivarsEqual = false; + } - //if (this._function != obj._function) - //{ - // ivarsEqual = false; - //} + if (!this._emitterSystem.Equals(obj._emitterSystem)) + { + ivarsEqual = false; + } - //if (this._emitterIdNumber != obj._emitterIdNumber) - //{ - // ivarsEqual = false; - //} + if (!this._location.Equals(obj._location)) + { + ivarsEqual = false; + } + + if (this._beams.Count != obj._beams.Count) + { + ivarsEqual = false; + } + else + { + for (int idx = 0; idx < this._beams.Count; idx++) + { + if (!this._beams[idx].Equals(obj._beams[idx])) + { + ivarsEqual = false; + } + } + } return ivarsEqual; } + /// /// HashCode Helper /// @@ -382,11 +460,30 @@ public override int GetHashCode() { int result = 0; - //result = GenerateHash(result) ^ this._emitterName.GetHashCode(); - //result = GenerateHash(result) ^ this._function.GetHashCode(); - //result = GenerateHash(result) ^ this._emitterIdNumber.GetHashCode(); + result = GenerateHash(result) ^ this._systemDataLength.GetHashCode(); + result = GenerateHash(result) ^ this._numberOfBeams.GetHashCode(); + result = GenerateHash(result) ^ this._paddingForEmissionSystem1.GetHashCode(); + + if (this._emitterSystem != null) + { + result = GenerateHash(result) ^ this._emitterSystem.GetHashCode(); + } + + if (this._location != null) + { + result = GenerateHash(result) ^ this._location.GetHashCode(); + } + + for (int idx = 0; idx < this._beams.Count; idx++) + { + if (this._beams[idx] != null) + { + result = GenerateHash(result) ^ this._beams[idx].GetHashCode(); + } + } return result; } + } } From 9e314c35eaf45d156c676115b9ab31a9ef089bf8 Mon Sep 17 00:00:00 2001 From: Jan Birkmann Date: Thu, 22 Jan 2026 15:01:35 +0100 Subject: [PATCH 3/3] Comments and Namespace changed --- CSharpDis7/Beam.cs | 6 ++---- CSharpDis7/ElectronicEmissionsPdu.cs | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/CSharpDis7/Beam.cs b/CSharpDis7/Beam.cs index 1b26ac7..42d8a80 100644 --- a/CSharpDis7/Beam.cs +++ b/CSharpDis7/Beam.cs @@ -32,10 +32,8 @@ // rights reserved. This work is licensed under the BSD open source license, // available at https://www.movesinstitute.org/licenses/bsd.html // -// Author: DMcG +// Author: Jan Birkmann (ELT Group Germany) // Modified for use with C#: -// - Peter Smith (Naval Air Warfare Center - Training Systems Division) -// - Zvonko Bostjancic (Blubit d.o.o. - zvonko.bostjancic@blubit.si) using System; using System.Collections.Generic; @@ -46,7 +44,7 @@ using System.Globalization; using OpenDis.Core; -namespace OpenDis.Dis2012 +namespace DISnet { /// /// Describes the scan volue of an emitter beam. Section 6.2.13. diff --git a/CSharpDis7/ElectronicEmissionsPdu.cs b/CSharpDis7/ElectronicEmissionsPdu.cs index 0ec6eea..193308e 100644 --- a/CSharpDis7/ElectronicEmissionsPdu.cs +++ b/CSharpDis7/ElectronicEmissionsPdu.cs @@ -48,7 +48,7 @@ namespace DISnet { /// - /// Section 5.3.7.1. Information about active electronic warfare (EW) emissions and active EW countermeasures shall be communicated using an Electromagnetic Emission PDU. NOT COMPLETE + /// Section 5.3.7.1. Information about active electronic warfare (EW) emissions and active EW countermeasures shall be communicated using an Electromagnetic Emission PDU. COMPLETE /// [Serializable] [XmlRoot]