Click here to Skip to main content
15,886,199 members
Articles / Programming Languages / C#

Using OpenTK/OpenAL to Develop Cross Platform DIS VOIP Application

Rate me:
Please Sign up or sign in to vote.
4.79/5 (8 votes)
15 Mar 2010BSD10 min read 44.8K   1.7K   24  
Application allows voice communications (VOIP) utilizing the Distributed Interactive Simulation protocol (IEEE 1278.1)
#region Header

// 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.

#endregion Header

namespace DISnet.Utilities
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;
    using System.Xml;
    using System.Xml.Serialization;

    using DISnet.DataStreamUtilities;

    /* Author Peter Smith (Naval Air Warfare Center - Training Systems Division) 01/23/2009
    * Modifications: none
    * Notes:
    */
    public class PDUProcessor
    {
        #region Fields

        protected const uint PDU_LENGTH_POSITION = 8;
        protected const uint PDU_TYPE_POSITION = 2;
        protected const uint PDU_VERSION_POSITION = 0;

        protected DISnet.DataStreamUtilities.EndianTypes.Endian edian = (BitConverter.IsLittleEndian ? DISnet.DataStreamUtilities.EndianTypes.Endian.LITTLE : DISnet.DataStreamUtilities.EndianTypes.Endian.BIG);
        protected System.Xml.Serialization.XmlSerializer xmlSerializedData;

        #endregion Fields

        #region Properties

        /// <summary>
        /// Type of endian used to process the data
        /// </summary>
        public DISnet.DataStreamUtilities.EndianTypes.Endian Endian
        {
            get
            {
                return this.edian;
            }

            set
            {
                this.edian = value;
            }
        }

        #endregion Properties

        #region Methods

        /// <summary>
        /// Converts a byte array into a DIS1998 PDU
        /// </summary>
        /// <param name="rawPDU">Byte array that hold raw 1998 PDU</param>
        /// <param name="pdu_type">Type of pdu</param>
        /// <returns>PDU object</returns>
        public DIS1998net.Pdu ConvertByteArrayToPDU1998(byte pdu_type, byte[] rawPDU, EndianTypes.Endian endian)
        {
            DIS1998net.Pdu pdu = DISnet.Utilities.PDUBank.GetPDU(pdu_type);
            DataInputStream ds = new DataInputStream(rawPDU, endian);
            
            //ReturnUnmarshalledPDU(pdu, ds);  //Removed this method to get rid of using Reflection
            return UnMarshalRawPDU(pdu_type, rawPDU, endian);
            //return pdu;
        }

        /// <summary>
        /// Provided as a means to return a string representation of the underlining PDU data.  Note format is not yet optimized.
        /// </summary>
        /// <param name="pdu">PDU to parse</param>
        /// <returns>StringBuilder that represents the state of the PDU</returns>
        public StringBuilder DecodePDU(object pdu)
        {
            StringBuilder sb = new StringBuilder();
            pdu.GetType().InvokeMember("reflection", System.Reflection.BindingFlags.InvokeMethod, null, pdu, new object[] { sb });

            return sb;
        }

        /// <summary>
        /// Provides a means of processing PDU data 
        /// </summary>
        /// <param name="buf">byte array containing the pdu data to process</param>
        /// <param name="endian">format of value types</param>
        /// <returns>Collection of PDUs which are represented in base object class</returns>
        public List<object> ProcessPDU(byte[] buf, DISnet.DataStreamUtilities.EndianTypes.Endian endian)
        {
            Endian = endian;
            return ProcessPDU(buf);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="buf"></param>
        /// <param name="endian"></param>
        /// <param name="length">The standard size of a PDU header.  The size of the pdu will be read from the header. 
        /// Note: This value could have been a const but wanted to be more flexible</param>
        /// <returns></returns>
        public object ProcessPDU(Stream stream, DISnet.DataStreamUtilities.EndianTypes.Endian endian)
        {
            Endian = endian;
            return ProcessPDU(stream);
        }

        public void ProcessPDU(Stream stream, DISnet.DataStreamUtilities.EndianTypes.Endian endian, out byte[] rawPDU)
        {
            Endian = endian;
            ProcessPDU(stream, out rawPDU);
        }

        //PES 09112009 Added to support passing back just the byte array
        /// <summary>
        /// Provides a means of processing PDU data 
        /// </summary>
        /// <param name="buf">byte array containing the pdu data to process</param>
        /// <param name="endian">format of value types</param>
        /// <returns>Collection of Raw byte[] PDUs</returns>
        public List<byte[]> ProcessRawPDU(byte[] buf, DISnet.DataStreamUtilities.EndianTypes.Endian endian)
        {
            Endian = endian;
            return ProcessRawPDU(buf);
        }

        //PES 09115009 Added to support passing back just the byte array into a Queue
        /// <summary>
        /// Provides a means of processing PDU data 
        /// </summary>
        /// <param name="buf">byte array containing the pdu data to process</param>
        /// <param name="endian">format of value types</param>
        /// <param name="dataQueue">Returns raw packets to a referenced Queue</param>
        public void ProcessRawPDU(byte[] buf, DISnet.DataStreamUtilities.EndianTypes.Endian endian, ref Queue<byte[]> dataQueue)
        {
            Endian = endian;

            foreach (byte[] pduRawByteArray in ProcessRawPDU(buf)) //Calling the method to get PDUs, increment through each in case more than one pdu in packet
            {
                dataQueue.Enqueue(pduRawByteArray);
            }
        }

        /// <summary>
        /// Returns an XML version of the reflected PDU
        /// </summary>
        /// <param name="pdu">PDU to reflect into XML</param>
        /// <returns>StringBuilder</returns>
        public StringBuilder XmlDecodePDU(object pdu)
        {
            StringBuilder sb = new StringBuilder();
            System.IO.StringWriter stringWriter = new System.IO.StringWriter();

            try
            {
                xmlSerializedData = new XmlSerializer(pdu.GetType());
                xmlSerializedData.Serialize(stringWriter, pdu);

            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                sb.Append(stringWriter.ToString());
                stringWriter.Close();
            }

            return sb;
        }

        //PES 09192009 This method used Reflection which is slow, new method 'UnMarshalRawPDU' should be used instead
        /// <summary>
        /// Unmarshal all data into the pdu object.  This method calls the all the base unmarshals.
        /// Deprecated:  This method used Reflection, use UnMarshalRawPDU method instead
        /// </summary>
        /// <param name="pdu">object where the unmarshalled data will be stored</param>
        /// <param name="dStream">location of where the unmarshalled data is located</param>
        private static void ReturnUnmarshalledPDU(object pdu, DataInputStream dStream)
        {
            //unmarshal is the method name found in each of the PDU classes
            pdu.GetType().InvokeMember("unmarshal", System.Reflection.BindingFlags.InvokeMethod, null, pdu, new object[] { dStream });
        }

        virtual protected void ProcessPDU(Stream stream, out byte[] rawData)
        {
            int upToPDULength = (int)PDU_LENGTH_POSITION + sizeof(UInt16);
            int pduLength = 0;

            long startingPosition = stream.Position;

            byte[] buf = new byte[upToPDULength];

            //Read in part of the stream up to the pdu length
            stream.Read(buf, 0, upToPDULength);

            try
            {
                if (this.edian == DISnet.DataStreamUtilities.EndianTypes.Endian.BIG)
                {
                    Array.Reverse(buf, (int)PDU_LENGTH_POSITION, 2);
                }

                pduLength = System.BitConverter.ToUInt16(buf, (int)PDU_LENGTH_POSITION);


                //Allocate space for the whole PDU
                rawData = new byte[pduLength];

                //Reset back to beginning
                stream.Position = startingPosition;

                //read in the whole PDU
                stream.Read(rawData, 0, pduLength);
            }
            catch (Exception ex)//Wow something bad just happened, could be bad/misalgined PDU
            {
                rawData = null;
            }
        }

        virtual protected object ProcessPDU(Stream stream)
        {
            int upToPDULength = (int)PDU_LENGTH_POSITION + sizeof(UInt16);
            int pduLength = 0;
            byte pdu_type;
            byte pdu_version;
            object PDU = null;

            long startingPosition = stream.Position;

            byte[] buf = new byte[upToPDULength];

            //Read in part of the stream up to the pdu length
            stream.Read(buf, 0, upToPDULength);

            try
            {
                if (this.edian == DISnet.DataStreamUtilities.EndianTypes.Endian.BIG)
                {
                    Array.Reverse(buf, (int)PDU_LENGTH_POSITION, 2);
                }

                pduLength = System.BitConverter.ToUInt16(buf, (int)PDU_LENGTH_POSITION);

                //Allocate space for the whole PDU
                byte[] PDUBufferStorage = new byte[pduLength];

                //Reset back to beginning
                stream.Position = startingPosition;

                //read in the whole PDU
                stream.Read(PDUBufferStorage, 0, pduLength);

                pdu_type = PDUBufferStorage[PDU_TYPE_POSITION];

                pdu_version = PDUBufferStorage[PDU_VERSION_POSITION];

                PDU = SwitchOnType(pdu_version, pdu_type, PDUBufferStorage);

            }
            catch (Exception ex)//Wow something bad just happened, could be bad/misalgined PDU
            {
                PDU = null;
            }

            return PDU;
        }

        /// <summary>
        /// Process a received PDU.  Note that a datastream can contain multiple PDUs.  Therefore a
        /// List is used to hold one or more after decoding.
        /// </summary>
        /// <param name="buf">byte array of PDU(s)</param>
        /// <returns>Collection of all PDU(s) decoded</returns>
        virtual protected List<object> ProcessPDU(byte[] buf)
        {
            List<object> pduCollection = new List<object>();

            if (buf.Length < 1)
            {
                return pduCollection;
            }

            int length = buf.Length;
            byte pdu_type;
            byte pdu_version;
            int countBytes = 0;
            uint pduLength = 0;

            //used to interate over all PDU(s) within the byte array
            while (countBytes < length)
            {
                try
                {
                    if (this.edian == DISnet.DataStreamUtilities.EndianTypes.Endian.BIG)
                    {
                        Array.Reverse(buf, (int)PDU_LENGTH_POSITION, 2);
                    }

                    pduLength = System.BitConverter.ToUInt16(buf, (int)PDU_LENGTH_POSITION + countBytes);

                    //Must be at end of datastream
                    if (pduLength == 0)
                        break;

                    pdu_type = buf[PDU_TYPE_POSITION + countBytes];

                    pdu_version = buf[PDU_VERSION_POSITION + countBytes];

                    byte[] PDUBufferStorage = new byte[pduLength];

                    //Could potentially be a problem since pduLength is an unsigned int,
                    //changed due to windows mobile does not accept a long for 4th parameter
                    Array.Copy(buf, countBytes, PDUBufferStorage, 0, (int)pduLength);

                    pduCollection.Add(SwitchOnType(pdu_version, pdu_type, PDUBufferStorage));

                    countBytes += (int)pduLength;

                }
                catch (Exception ex)//Wow something bad just happened, could be bad/misalgined PDU
                {
                    break;
                }
            }

            return pduCollection;
        }

        //PES 09112009 Added to support passing back just the byte array
        /// <summary>
        /// Process a received PDU.  Note that a datastream can contain multiple PDUs.  Therefore a
        /// List is used to hold one or more after decoding.
        /// </summary>
        /// <param name="buf">byte array of PDU(s)</param>
        /// <returns>Collection of all PDU(s) in raw byte format</returns>
        virtual protected List<byte[]> ProcessRawPDU(byte[] buf)
        {
            List<byte[]> pduCollection = new List<byte[]>();

            if (buf.Length < 1)
            {
                return pduCollection;
            }

            int length = buf.Length;
            byte pdu_type;
            byte pdu_version;
            int countBytes = 0;
            uint pduLength = 0;

            //used to interate over all PDU(s) within the byte array
            while (countBytes < length)
            {
                try
                {
                    if (this.edian == DISnet.DataStreamUtilities.EndianTypes.Endian.BIG)
                    {
                        Array.Reverse(buf, (int)PDU_LENGTH_POSITION + countBytes, 2);
                    }

                    pduLength = System.BitConverter.ToUInt16(buf, (int)PDU_LENGTH_POSITION + countBytes);

                    //Must be at end of datastream
                    if (pduLength == 0)
                        break;

                    pdu_type = buf[PDU_TYPE_POSITION + countBytes];

                    pdu_version = buf[PDU_VERSION_POSITION + countBytes];

                    byte[] PDUBufferStorage = new byte[pduLength];

                    //Could potentially be a problem since pduLength is an unsigned int,
                    //changed due to windows mobile does not accept a long for 4th parameter
                    Array.Copy(buf, countBytes, PDUBufferStorage, 0, (int)pduLength); 

                    pduCollection.Add(PDUBufferStorage);

                    countBytes += (int)pduLength;

                }
                catch (Exception ex)//Wow something bad just happened, could be bad/misalgined PDU
                {
                    break;
                }
            }

            return pduCollection;
        }

        ///<summary>
        ///Returns an instance of the PDU based upon the pdu type passed in.  Note PDU will be represented as an Object for simplicity.
        ///</summary>
        ///<param name="pdu_version">Version of IEEE standard</param>
        ///<param name="pdu_type">Type of PDU</param>
        ///<param name="ds">PDU byte array containing the data</param>
        ///<returns></returns>         
        virtual protected object SwitchOnType(byte pdu_version, uint pdu_type, byte[] ds)
        {
            object pdu = null;

            DataInputStream dStream = new DataInputStream(ds, this.Endian);

            switch (pdu_version)
            {
                case 5: //1995
                    break;
                case 6: //1998
                    //pdu = DISnet.Utilities.PDUBank.GetPDU(pdu_type);
                    pdu = UnMarshalRawPDU((PDUTypes.PDUType1998)pdu_type, dStream);
                    break;
                default:
                    break;
            }

            //if (pdu != null)
            //{
            //    //Call the method of the underlining Type vice the Upper class method.
            //    ReturnUnmarshalledPDU(pdu, dStream);
            //}

            return pdu;
        }

        //PES 09182009  Added to work with Mobile 
        /// <summary>
        /// Used to unmarshal data back into the correct PDU type.
        /// </summary>
        /// <param name="pdu_type">PDU type</param>
        /// <param name="rawPDU">byte array containing the raw packets</param>
        /// <param name="endian">Endian type</param>
        /// <returns></returns>
        public static DIS1998net.Pdu UnMarshalRawPDU(byte pdu_type, byte[] rawPDU, DISnet.DataStreamUtilities.EndianTypes.Endian endian)
        {
            DataInputStream ds = new DataInputStream(rawPDU, endian);
            return UnMarshalRawPDU((PDUTypes.PDUType1998)pdu_type, ds);
        }
        //PES 09182009  Added to work with Mobile
        /// <summary>
        /// Used to unmarshal data back into the correct PDU type.
        /// </summary>
        /// <param name="pdu_type">PDU type</param>
        /// <param name="ds">Datastream which contains the raw packet and Endian Type</param>
        /// <returns></returns>
        public static DIS1998net.Pdu UnMarshalRawPDU(byte pdu_type, DataInputStream ds)
        {
            return UnMarshalRawPDU((PDUTypes.PDUType1998)pdu_type, ds);
        }

        //PES 09182009  Added to work with Mobile 
        /// <summary>
        /// Used to unmarshal data back into the correct PDU type.
        /// </summary>
        /// <param name="pdu_type">PDU type</param>
        /// <param name="rawPDU">byte array containing the raw packets</param>
        /// <param name="endian">Endian type</param>
        /// <returns></returns>
        public static DIS1998net.Pdu UnMarshalRawPDU(DISnet.Utilities.PDUTypes.PDUType1998 pdu_type, byte[] rawPDU, DISnet.DataStreamUtilities.EndianTypes.Endian endian)
        {
            DataInputStream ds = new DataInputStream(rawPDU, endian);
            return UnMarshalRawPDU(pdu_type, ds);
        }

        //PES 09182009  Added to work with Mobile
        /// <summary>
        /// Used to unmarshal data back into the correct PDU type.
        /// </summary>
        /// <param name="pdu_type">PDU type</param>
        /// <param name="ds">Datastream which contains the raw packet and Endian Type</param>
        /// <returns></returns>
        public static DIS1998net.Pdu UnMarshalRawPDU(DISnet.Utilities.PDUTypes.PDUType1998 pdu_type, DataInputStream ds)
        {
            DIS1998net.Pdu pdu = new DIS1998net.Pdu();

            switch (pdu_type)
            {
                case PDUTypes.PDUType1998.PDU_ENTITY_STATE:
                    DIS1998net.EntityStatePdu EntityStatePdu = new DIS1998net.EntityStatePdu();
                    EntityStatePdu.unmarshal(ds);
                    pdu = (DIS1998net.Pdu)EntityStatePdu;
                    break;
                case PDUTypes.PDUType1998.PDU_FIRE:
                    DIS1998net.FirePdu FirePdu = new DIS1998net.FirePdu();
                    FirePdu.unmarshal(ds);
                    pdu = (DIS1998net.Pdu)FirePdu;
                    break;
                case PDUTypes.PDUType1998.PDU_DETONATION:
                    DIS1998net.DetonationPdu DetonationPdu = new DIS1998net.DetonationPdu();
                    DetonationPdu.unmarshal(ds);
                    pdu = (DIS1998net.Pdu)DetonationPdu;
                    break;
                case PDUTypes.PDUType1998.PDU_COLLISION:
                    DIS1998net.CollisionPdu CollisionPdu = new DIS1998net.CollisionPdu();
                    CollisionPdu.unmarshal(ds);
                    pdu = (DIS1998net.Pdu)CollisionPdu;
                    break;
                case PDUTypes.PDUType1998.PDU_SERVICE_REQUEST:
                    DIS1998net.ServiceRequestPdu ServiceRequestPdu = new DIS1998net.ServiceRequestPdu();
                    ServiceRequestPdu.unmarshal(ds);
                    pdu = (DIS1998net.Pdu)ServiceRequestPdu;
                    break;
                case PDUTypes.PDUType1998.PDU_RESUPPLY_OFFER:
                    DIS1998net.ResupplyOfferPdu ResupplyOfferPdu = new DIS1998net.ResupplyOfferPdu();
                    ResupplyOfferPdu.unmarshal(ds);
                    pdu = (DIS1998net.Pdu)ResupplyOfferPdu;
                    break;
                case PDUTypes.PDUType1998.PDU_RESUPPLY_RECEIVED:
                    DIS1998net.ResupplyReceivedPdu ResupplyReceivedPdu = new DIS1998net.ResupplyReceivedPdu();
                    ResupplyReceivedPdu.unmarshal(ds);
                    pdu = (DIS1998net.Pdu)ResupplyReceivedPdu;
                    break;
                case PDUTypes.PDUType1998.PDU_RESUPPLY_CANCEL:
                    DIS1998net.ResupplyCancelPdu ResupplyCancelPdu = new DIS1998net.ResupplyCancelPdu();
                    ResupplyCancelPdu.unmarshal(ds);
                    pdu = (DIS1998net.Pdu)ResupplyCancelPdu;
                    break;
                case PDUTypes.PDUType1998.PDU_REPAIR_COMPLETE:
                    DIS1998net.RepairCompletePdu RepairCompletePdu = new DIS1998net.RepairCompletePdu();
                    RepairCompletePdu.unmarshal(ds);
                    pdu = (DIS1998net.Pdu)RepairCompletePdu;
                    break;
                case PDUTypes.PDUType1998.PDU_REPAIR_RESPONSE:
                    DIS1998net.RepairResponsePdu RepairResponsePdu = new DIS1998net.RepairResponsePdu();
                    RepairResponsePdu.unmarshal(ds);
                    pdu = (DIS1998net.Pdu)RepairResponsePdu;
                    break;
                case PDUTypes.PDUType1998.PDU_CREATE_ENTITY:
                    DIS1998net.CreateEntityPdu CreateEntityPdu = new DIS1998net.CreateEntityPdu();
                    CreateEntityPdu.unmarshal(ds);
                    pdu = (DIS1998net.Pdu)CreateEntityPdu;
                    break;
                case PDUTypes.PDUType1998.PDU_REMOVE_ENTITY:
                    DIS1998net.RemoveEntityPdu RemoveEntityPdu = new DIS1998net.RemoveEntityPdu();
                    RemoveEntityPdu.unmarshal(ds);
                    pdu = (DIS1998net.Pdu)RemoveEntityPdu;
                    break;
                case PDUTypes.PDUType1998.PDU_START_RESUME:
                    DIS1998net.StartResumePdu StartResumePdu = new DIS1998net.StartResumePdu();
                    StartResumePdu.unmarshal(ds);
                    pdu = (DIS1998net.Pdu)StartResumePdu;
                    break;
                case PDUTypes.PDUType1998.PDU_ACKNOWLEDGE:
                    DIS1998net.AcknowledgePdu AcknowledgePdu = new DIS1998net.AcknowledgePdu();
                    AcknowledgePdu.unmarshal(ds);
                    pdu = (DIS1998net.Pdu)AcknowledgePdu;
                    break;
                case PDUTypes.PDUType1998.PDU_ACTION_REQUEST:
                    DIS1998net.ActionRequestPdu ActionRequestPdu = new DIS1998net.ActionRequestPdu();
                    ActionRequestPdu.unmarshal(ds);
                    pdu = (DIS1998net.Pdu)ActionRequestPdu;
                    break;
                case PDUTypes.PDUType1998.PDU_ACTION_RESPONSE:
                    DIS1998net.ActionResponsePdu ActionResponsePdu = new DIS1998net.ActionResponsePdu();
                    ActionResponsePdu.unmarshal(ds);
                    pdu = (DIS1998net.Pdu)ActionResponsePdu;
                    break;
                case PDUTypes.PDUType1998.PDU_DATA_QUERY:
                    DIS1998net.DataQueryPdu DataQueryPdu = new DIS1998net.DataQueryPdu();
                    DataQueryPdu.unmarshal(ds);
                    pdu = (DIS1998net.Pdu)DataQueryPdu;
                    break;
                case PDUTypes.PDUType1998.PDU_SET_DATA:
                    DIS1998net.SetDataPdu SetDataPdu = new DIS1998net.SetDataPdu();
                    SetDataPdu.unmarshal(ds);
                    pdu = (DIS1998net.Pdu)SetDataPdu;
                    break;
                case PDUTypes.PDUType1998.PDU_EVENT_REPORT:
                    DIS1998net.EventReportPdu EventReportPdu = new DIS1998net.EventReportPdu();
                    EventReportPdu.unmarshal(ds);
                    pdu = (DIS1998net.Pdu)EventReportPdu;
                    break;
                case PDUTypes.PDUType1998.PDU_COMMENT:
                    DIS1998net.CommentPdu CommentPdu = new DIS1998net.CommentPdu();
                    CommentPdu.unmarshal(ds);
                    pdu = (DIS1998net.Pdu)CommentPdu;
                    break;
                case PDUTypes.PDUType1998.PDU_STOP_FREEZE:
                    DIS1998net.StopFreezePdu StopFreezePdu = new DIS1998net.StopFreezePdu();
                    StopFreezePdu.unmarshal(ds);
                    pdu = (DIS1998net.Pdu)StopFreezePdu;
                    break;
                case PDUTypes.PDUType1998.PDU_SIGNAL:
                    DIS1998net.SignalPdu SignalPdu = new DIS1998net.SignalPdu();
                    SignalPdu.unmarshal(ds);
                    pdu = (DIS1998net.Pdu)SignalPdu;
                    break;
                case PDUTypes.PDUType1998.PDU_TRANSMITTER:
                    DIS1998net.TransmitterPdu transmitterPdu = new DIS1998net.TransmitterPdu();
                    transmitterPdu.unmarshal(ds);
                    pdu = (DIS1998net.Pdu)transmitterPdu;
                    break;
            }

            return pdu;
        }

        #endregion Methods
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The BSD License


Written By
Software Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions