// This method returns the index to the first
        // byte of the user data after FSPEC, SIC and SAC
        // assumes that the first three octets from the data
        // block are removed from the buffer
        public static int GetFirstDataIndex(byte[] Data)
        {
            // Determine Length of FSPEC fields in bytes
            int FSPEC_Length = ASTERIX.DetermineLenghtOfFSPEC(Data);

            // Determine SIC/SAC Index
            int SIC_Index = FSPEC_Length;
            int SAC_Index = SIC_Index + 1;

            return(SAC_Index + 1);
        }
Example #2
0
        private void SetNewConnection()
        {
            SharedData.ConnName = (string)this.listBoxConnName.Items[this.listBoxConnName.SelectedIndex];
            SharedData.CurrentInterfaceIPAddress = (string)this.listBoxLocalAddr.Items[this.listBoxConnName.SelectedIndex];
            SharedData.CurrentMulticastAddress   = (string)this.listBoxIPAddress.Items[this.listBoxConnName.SelectedIndex];
            SharedData.Current_Port = int.Parse((string)this.listBoxPort.Items[this.listBoxConnName.SelectedIndex]);

            if (ASTERIX.ReinitializeSocket() != true)
            {
                SharedData.ResetConnectionParameters();
            }
        }
        public static string DecodeAsterixData(string FileName)
        {
            long Position = 0;
            // get total byte length of the file
            long TotalBytes = new System.IO.FileInfo(FileName).Length;

            try
            {
                // Open file for reading
                System.IO.FileStream FileStream = new System.IO.FileStream(FileName, System.IO.FileMode.Open, System.IO.FileAccess.Read);

                // attach filestream to binary reader
                System.IO.BinaryReader BinaryReader = new System.IO.BinaryReader(FileStream);

                while (Position < TotalBytes)
                {
                    // First determine the size of the message
                    // octet    data
                    // 0        ASTERIX CATEGORY
                    // 1 .. 2   LENGTH OF MESSAGE BLOCK
                    byte[] Data_Block_Buffer    = BinaryReader.ReadBytes((Int32)3);
                    int    LengthOfMessageBlock = ASTERIX.ExtractLengthOfDataBlockInBytes_Int(Data_Block_Buffer);

                    BinaryReader.BaseStream.Position = BinaryReader.BaseStream.Position - 3;
                    // Now read the message and pass it to the parser
                    // for decoding
                    Data_Block_Buffer = BinaryReader.ReadBytes((Int32)LengthOfMessageBlock);
                    ExtractAndDecodeASTERIX_CAT_DataBlock(Data_Block_Buffer, false);
                    Position = BinaryReader.BaseStream.Position;
                }

                // close file reader
                FileStream.Close();
                FileStream.Dispose();
                BinaryReader.Close();
            }
            catch (Exception Exception)
            {
                // Error
                MessageBox.Show("Exception caught in process: {0}", Exception.ToString());
            }

            return("Read " + Position.ToString() + " of total " + TotalBytes.ToString() + " bytes");
        }
Example #4
0
        // Do not bother to decode CAT244, not really important for us. Just determine that
        // it is present for now.
        public string Decode(byte[] Data, string Time)
        {
            // Define output data buffer
            string DataOut;

            // Determine Length of FSPEC fields in bytes
            int FSPEC_Length = ASTERIX.DetermineLenghtOfFSPEC(Data);

            // Determine SIC/SAC Index
            // No SIC/SAC for CAT244

            // Extract SIC/SAC Indexes.
            DataOut = "N/A" + '/' + "N/A";

            // Creates and initializes a BitVector32 with all bit flags set to FALSE.
            BitVector32 FourFSPECOctets = ASTERIX.GetFourFSPECOctets(Data);

            // Return decoded data
            return(DataOut);
        }
        public string[] Decode(byte[] DataBlockBuffer, string Time, out int NumOfMessagesDecoded)
        {
            // Define output data buffer
            string[] DataOut = new string[1000];

            // Determine the size of the datablock
            int LengthOfDataBlockInBytes = DataBlockBuffer.Length;

            // Index into the array of record strings
            int DataOutIndex = 0;

            // Reset buffer indexes
            CurrentDataBufferOctalIndex = 0;
            int DataBufferIndexForThisExtraction = 0;

            // SIC/SAC Indexes
            int SIC_Index = 0;
            int SAC_Index = 0;

            // Save off SIC/SAC and time in the case they are not present
            // in each message. Some implementation have it only in the first record
            int SIC = 0;
            int SAC = 0;

            // Lenght of the current record's FSPECs
            int FSPEC_Length = 0;

            // The four possible FSPEC octets
            BitVector32 FourFSPECOctets = new BitVector32();

            while ((DataBufferIndexForThisExtraction) < LengthOfDataBlockInBytes)
            {
                // Assume that there will be no more than 300 bytes in one record
                byte[] LocalSingleRecordBuffer = new byte[3000];

                Array.Copy(DataBlockBuffer, DataBufferIndexForThisExtraction, LocalSingleRecordBuffer, 0, (LengthOfDataBlockInBytes - DataBufferIndexForThisExtraction));

                // Get all four data words, but use only the number specifed
                // by the length of FSPEC words
                FourFSPECOctets = ASTERIX.GetFourFSPECOctets(LocalSingleRecordBuffer);

                // Determine Length of FSPEC fields in bytes
                FSPEC_Length = ASTERIX.DetermineLenghtOfFSPEC(LocalSingleRecordBuffer);

                // Check wether 010 is present
                if (FourFSPECOctets[Bit_Ops.Bit7] == true)
                {
                    // Determine SIC/SAC Index
                    SIC_Index = FSPEC_Length;
                    SAC_Index = SIC_Index + 1;

                    // Extract SIC/SAC Indexes.
                    DataOut[DataOutIndex] = LocalSingleRecordBuffer[SIC_Index].ToString() + '/' + LocalSingleRecordBuffer[SAC_Index].ToString();

                    // Save off data for other records
                    SIC = LocalSingleRecordBuffer[SIC_Index];
                    SAC = LocalSingleRecordBuffer[SAC_Index];

                    // Save of the current data buffer index so it can be used by
                    // Decoder
                    CurrentDataBufferOctalIndex = SAC_Index + 1;
                }
                else
                {
                    CurrentDataBufferOctalIndex = FSPEC_Length;
                    // Extract SIC/SAC Indexes.
                    DataOut[DataOutIndex] = SIC.ToString() + '/' + SAC.ToString();
                }

                ///////////////////////////////////////////////////////////////////////////
                // Populate the current SIC/SAC and Time stamp for this meesage
                //
                I048DataItems[ItemIDToIndex("010")].value =
                    new ASTERIX.SIC_SAC_Time(SIC, SAC, ASTERIX.TimeOfReception);

                Reset_Currently_Present_Flags();

                // Loop for each FSPEC and determine what data item is present
                for (int FSPEC_Index = 1; FSPEC_Index <= FSPEC_Length; FSPEC_Index++)
                {
                    switch (FSPEC_Index)
                    {
                    case 1:

                        // 010 Data Source Identifier
                        if (FourFSPECOctets[Bit_Ops.Bit7] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  010:T";
                            I048DataItems[ItemIDToIndex("010")].HasBeenPresent   = true;
                            I048DataItems[ItemIDToIndex("010")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  010:F";
                        }

                        // 140 Time-of-Day
                        if (FourFSPECOctets[Bit_Ops.Bit6] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  140:T";
                            I048DataItems[ItemIDToIndex("140")].HasBeenPresent   = true;
                            I048DataItems[ItemIDToIndex("140")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  140:F";
                        }

                        // 020 Target Report Descriptor
                        if (FourFSPECOctets[Bit_Ops.Bit5] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  020:T";
                            I048DataItems[ItemIDToIndex("020")].HasBeenPresent   = true;
                            I048DataItems[ItemIDToIndex("020")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  020:F";
                        }

                        // 040 Measured Position in Slant Polar Coordinates
                        if (FourFSPECOctets[Bit_Ops.Bit4] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  040:T";
                            I048DataItems[ItemIDToIndex("040")].HasBeenPresent   = true;
                            I048DataItems[ItemIDToIndex("040")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  040:F";
                        }

                        // 070 Mode-3/A Code in Octal Representation
                        if (FourFSPECOctets[Bit_Ops.Bit3] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  070:T";
                            I048DataItems[ItemIDToIndex("070")].HasBeenPresent   = true;
                            I048DataItems[ItemIDToIndex("070")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  070:F";
                        }

                        // 090 Flight Level in Binary Representation
                        if (FourFSPECOctets[Bit_Ops.Bit2] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  090:T";
                            I048DataItems[ItemIDToIndex("090")].HasBeenPresent   = true;
                            I048DataItems[ItemIDToIndex("090")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  090:F";
                        }

                        // 130 Radar Plot Characteristics
                        if (FourFSPECOctets[Bit_Ops.Bit1] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  130:T";
                            I048DataItems[ItemIDToIndex("130")].HasBeenPresent   = true;
                            I048DataItems[ItemIDToIndex("130")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  130:F";
                        }

                        break;

                    case 2:

                        // 220 Aircraft Address
                        if (FourFSPECOctets[Bit_Ops.Bit15] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  220:T";
                            I048DataItems[ItemIDToIndex("220")].HasBeenPresent   = true;
                            I048DataItems[ItemIDToIndex("220")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  220:F";
                        }

                        // 240 Aircraft Identification
                        if (FourFSPECOctets[Bit_Ops.Bit14] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  240:T";
                            I048DataItems[ItemIDToIndex("240")].HasBeenPresent   = true;
                            I048DataItems[ItemIDToIndex("240")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  240:F";
                        }

                        // 250 Mode S MB Data
                        if (FourFSPECOctets[Bit_Ops.Bit13] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  250:T";
                            I048DataItems[ItemIDToIndex("250")].HasBeenPresent   = true;
                            I048DataItems[ItemIDToIndex("250")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  250:F";
                        }

                        // 161 Track Number
                        if (FourFSPECOctets[Bit_Ops.Bit12] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  161:T";
                            I048DataItems[ItemIDToIndex("161")].HasBeenPresent   = true;
                            I048DataItems[ItemIDToIndex("161")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  161:F";
                        }

                        // 042 Calculated Position in Cartesian Coordinates
                        if (FourFSPECOctets[Bit_Ops.Bit11] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  042:T";
                            I048DataItems[ItemIDToIndex("042")].HasBeenPresent   = true;
                            I048DataItems[ItemIDToIndex("042")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  042:F";
                        }

                        // 200 Calculated Track Velocity in Polar Representation
                        if (FourFSPECOctets[Bit_Ops.Bit10] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  200:T";
                            I048DataItems[ItemIDToIndex("200")].HasBeenPresent   = true;
                            I048DataItems[ItemIDToIndex("200")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  200:F";
                        }

                        // 170 Track Status
                        if (FourFSPECOctets[Bit_Ops.Bit9] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  170:T";
                            I048DataItems[ItemIDToIndex("170")].HasBeenPresent   = true;
                            I048DataItems[ItemIDToIndex("170")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  170:F";
                        }

                        break;

                    case 3:

                        // 210 Track Quality
                        if (FourFSPECOctets[Bit_Ops.Bit23] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  210:T";
                            I048DataItems[ItemIDToIndex("210")].HasBeenPresent   = true;
                            I048DataItems[ItemIDToIndex("210")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  210:F";
                        }

                        // 030 Warning/Error Conditions
                        if (FourFSPECOctets[Bit_Ops.Bit22] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  030:T";
                            I048DataItems[ItemIDToIndex("030")].HasBeenPresent   = true;
                            I048DataItems[ItemIDToIndex("030")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  030:F";
                        }

                        // 080 Mode-3/A Code Confidence Indicator
                        if (FourFSPECOctets[Bit_Ops.Bit21] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  080:T";
                            I048DataItems[ItemIDToIndex("080")].HasBeenPresent   = true;
                            I048DataItems[ItemIDToIndex("080")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  080:F";
                        }

                        // 100 Mode-C Code and Confidence Indicator
                        if (FourFSPECOctets[Bit_Ops.Bit20] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  100:T";
                            I048DataItems[ItemIDToIndex("100")].HasBeenPresent   = true;
                            I048DataItems[ItemIDToIndex("100")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  100:F";
                        }

                        // 110 Height Measured by 3D Radar
                        if (FourFSPECOctets[Bit_Ops.Bit19] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  110:T";
                            I048DataItems[ItemIDToIndex("110")].HasBeenPresent   = true;
                            I048DataItems[ItemIDToIndex("110")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  110:F";
                        }

                        // 120 Radial Doppler Speed
                        if (FourFSPECOctets[Bit_Ops.Bit18] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  120:T";
                            I048DataItems[ItemIDToIndex("120")].HasBeenPresent   = true;
                            I048DataItems[ItemIDToIndex("120")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  120:F";
                        }

                        // 230 Communications / ACAS Capability and Flight Status
                        if (FourFSPECOctets[Bit_Ops.Bit17] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  230:T";
                            I048DataItems[ItemIDToIndex("230")].HasBeenPresent   = true;
                            I048DataItems[ItemIDToIndex("230")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  230:F";
                        }

                        break;

                    case 4:

                        // 260 ACAS Resolution Advisory Report
                        if (FourFSPECOctets[Bit_Ops.Bit31] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  260:T";
                            I048DataItems[ItemIDToIndex("260")].HasBeenPresent   = true;
                            I048DataItems[ItemIDToIndex("260")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  260:F";
                        }

                        // 55 Mode-1 Code in Octal Representation
                        if (FourFSPECOctets[Bit_Ops.Bit30] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  55:T";
                            I048DataItems[ItemIDToIndex("055")].HasBeenPresent   = true;
                            I048DataItems[ItemIDToIndex("055")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  55:F";
                        }

                        // 50 Mode-2 Code in Octal Representation
                        if (FourFSPECOctets[Bit_Ops.Bit29] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  50:T";
                            I048DataItems[ItemIDToIndex("050")].HasBeenPresent   = true;
                            I048DataItems[ItemIDToIndex("050")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  50:F";
                        }

                        // 65 Mode-1 Code Confidence Indicator
                        if (FourFSPECOctets[Bit_Ops.Bit28] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  65:T";
                            I048DataItems[ItemIDToIndex("065")].HasBeenPresent   = true;
                            I048DataItems[ItemIDToIndex("065")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  65:F";
                        }

                        // 60 Mode-2 Code Confidence Indicator
                        if (FourFSPECOctets[Bit_Ops.Bit27] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  60:T";
                            I048DataItems[ItemIDToIndex("060")].HasBeenPresent   = true;
                            I048DataItems[ItemIDToIndex("060")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  60:F";
                        }


                        if (FourFSPECOctets[Bit_Ops.Bit26] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + " SPI:T";
                            I048DataItems[ItemIDToIndex("SPI")].HasBeenPresent   = true;
                            I048DataItems[ItemIDToIndex("SPI")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + " SPI:F";
                        }

                        if (FourFSPECOctets[Bit_Ops.Bit25] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  Reserved Expansion";
                        }

                        break;

                    // Handle errors
                    default:
                        DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  UKN:T";
                        break;
                    }
                }

                DataOutIndex++;
                CAT48DecodeAndStore.Do(LocalSingleRecordBuffer);
                DataBufferIndexForThisExtraction = DataBufferIndexForThisExtraction + CurrentDataBufferOctalIndex + 1;
            }

            // Return decoded data
            NumOfMessagesDecoded = DataOutIndex;
            return(DataOut);
        }
Example #6
0
        public string Decode(byte[] Data, string Time)
        {
            // Define output data buffer
            string DataOut;

            // Determine Length of FSPEC fields in bytes
            int FSPEC_Length = ASTERIX.DetermineLenghtOfFSPEC(Data);

            // Determine SIC/SAC Index
            int SIC_Index = 3 + FSPEC_Length;
            int SAC_Index = SIC_Index + 1;

            // Extract SIC/SAC Indexes.
            DataOut = Data[SIC_Index].ToString() + '/' + Data[SAC_Index].ToString();

            // Creates and initializes a BitVector32 with all bit flags set to FALSE.
            BitVector32 FourFSPECOctets = ASTERIX.GetFourFSPECOctets(Data);

            // Loop for each FSPEC and determine what data item is present
            for (int FSPEC_Index = 1; FSPEC_Index <= FSPEC_Length; FSPEC_Index++)
            {
                switch (FSPEC_Index)
                {
                case 1:

                    // 010 Data Source Identifier
                    if (FourFSPECOctets[Bit_Ops.Bit7] == true)
                    {
                        DataOut = DataOut + "  010:T";
                        I065DataItems[ItemIDToIndex("010")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  010:F";
                    }

                    // 000 Message Type
                    if (FourFSPECOctets[Bit_Ops.Bit6] == true)
                    {
                        DataOut = DataOut + "  000:T";
                        I065DataItems[ItemIDToIndex("000")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  000:F";
                    }

                    // 015 Service Identification
                    if (FourFSPECOctets[Bit_Ops.Bit5] == true)
                    {
                        DataOut = DataOut + "  015:T";
                        I065DataItems[ItemIDToIndex("015")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  015:F";
                    }

                    // 030 Time of Message
                    if (FourFSPECOctets[Bit_Ops.Bit4] == true)
                    {
                        DataOut = DataOut + "  030:T";
                        I065DataItems[ItemIDToIndex("030")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  030:F";
                    }

                    // 020 Batch Number
                    if (FourFSPECOctets[Bit_Ops.Bit3] == true)
                    {
                        DataOut = DataOut + "  020:T";
                        I065DataItems[ItemIDToIndex("020")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  020:F";
                    }

                    // 040 SDPS Configuration and Status
                    if (FourFSPECOctets[Bit_Ops.Bit2] == true)
                    {
                        DataOut = DataOut + "  040:T";
                        I065DataItems[ItemIDToIndex("040")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  040:F";
                    }

                    // 050 Service Status Report
                    if (FourFSPECOctets[Bit_Ops.Bit1] == true)
                    {
                        DataOut = DataOut + "  050:T";
                        I065DataItems[ItemIDToIndex("050")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  050:F";
                    }

                    break;

                // Handle errors
                default:
                    DataOut = DataOut + "  UKN:T";
                    break;
                }

                CAT65DecodeAndStore.Do(Data);
            }

            // Return decoded data
            return(DataOut);
        }
Example #7
0
        public string Decode(byte[] Data, string Time)
        {
            // Define output data buffer
            string DataOut;

            // Determine Length of FSPEC fields in bytes
            int FSPEC_Length = ASTERIX.DetermineLenghtOfFSPEC(Data);

            // Determine SIC/SAC Index
            int SIC_Index = 3 + FSPEC_Length;
            int SAC_Index = SIC_Index + 1;

            // Extract SIC/SAC Indexes.
            DataOut = Data[SIC_Index].ToString() + '/' + Data[SAC_Index].ToString();

            // Creates and initializes a BitVector32 with all bit flags set to FALSE.
            BitVector32 FourFSPECOctets = ASTERIX.GetFourFSPECOctets(Data);

            // Loop for each FSPEC and determine what data item is present
            for (int FSPEC_Index = 1; FSPEC_Index <= FSPEC_Length; FSPEC_Index++)
            {
                switch (FSPEC_Index)
                {
                case 1:

                    // 010 Data Source Identifier
                    if (FourFSPECOctets[Bit_Ops.Bit0] == true)
                    {
                        DataOut = DataOut + "  010:T";
                        I008DataItems[ItemIDToIndex("010")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  010:F";
                    }

                    // 000 Message Type
                    if (FourFSPECOctets[Bit_Ops.Bit1] == true)
                    {
                        DataOut = DataOut + "  000:T";
                        I008DataItems[ItemIDToIndex("000")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  000:F";
                    }

                    // 020 Vector Qualifier
                    if (FourFSPECOctets[Bit_Ops.Bit2] == true)
                    {
                        DataOut = DataOut + "  020:T";
                        I008DataItems[ItemIDToIndex("020")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  020:F";
                    }

                    // 036 Sequence of Cartesian Vectors in SPF Notation
                    if (FourFSPECOctets[Bit_Ops.Bit3] == true)
                    {
                        DataOut = DataOut + "  036:T";
                        I008DataItems[ItemIDToIndex("036")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  036:F";
                    }

                    // 034 Sequence of Polar Vectors in SPF Notation
                    if (FourFSPECOctets[Bit_Ops.Bit4] == true)
                    {
                        DataOut = DataOut + "  034:T";
                        I008DataItems[ItemIDToIndex("034")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  034:F";
                    }

                    // 040 Contour Identifier
                    if (FourFSPECOctets[Bit_Ops.Bit5] == true)
                    {
                        DataOut = DataOut + "  040:T";
                        I008DataItems[ItemIDToIndex("040")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  040:F";
                    }

                    // 050 Sequence of Contour Points in SPF Notation
                    if (FourFSPECOctets[Bit_Ops.Bit6] == true)
                    {
                        DataOut = DataOut + "  050:T";
                        I008DataItems[ItemIDToIndex("050")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  050:F";
                    }

                    break;

                case 2:

                    // 090 Time of Day
                    if (FourFSPECOctets[Bit_Ops.Bit8] == true)
                    {
                        DataOut = DataOut + "  090:T";
                        I008DataItems[ItemIDToIndex("090")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  090:F";
                    }

                    // 100 Processing Status
                    if (FourFSPECOctets[Bit_Ops.Bit9] == true)
                    {
                        DataOut = DataOut + "  100:T";
                        I008DataItems[ItemIDToIndex("100")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  100:F";
                    }

                    // 110 Station Configuration Status
                    if (FourFSPECOctets[Bit_Ops.Bit10] == true)
                    {
                        DataOut = DataOut + "  110:T";
                        I008DataItems[ItemIDToIndex("110")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  110:F";
                    }

                    // 120 Total Number of Items Constituting One Weather Picture
                    if (FourFSPECOctets[Bit_Ops.Bit11] == true)
                    {
                        DataOut = DataOut + "  120:T";
                        I008DataItems[ItemIDToIndex("120")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  120:F";
                    }

                    // 038 Sequence of Weather Vectors in SPF Notation
                    if (FourFSPECOctets[Bit_Ops.Bit12] == true)
                    {
                        DataOut = DataOut + "  038:T";
                        I008DataItems[ItemIDToIndex("038")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  038:F";
                    }

                    break;

                // Handle errors
                default:
                    DataOut = DataOut + "  UKN:T";
                    break;
                }

                CAT08DecodeAndStore.Do(Data);
            }

            // Return decoded data
            return(DataOut);
        }
Example #8
0
        public string Decode(byte[] Data, string Time)
        {
            // Define output data buffer
            string DataOut;

            // Determine Length of FSPEC fields in bytes
            int FSPEC_Length = ASTERIX.DetermineLenghtOfFSPEC(Data);

            // Determine SIC/SAC Index
            int SIC_Index = 2 + FSPEC_Length;
            int SAC_Index = SIC_Index + 1;

            // Extract SIC/SAC Indexes.
            DataOut = Data[SIC_Index].ToString() + '/' + Data[SAC_Index].ToString();

            // Creates and initializes a BitVector32 with all bit flags set to FALSE.
            BitVector32 FourFSPECOctets = ASTERIX.GetFourFSPECOctets(Data);

            // Loop for each FSPEC and determine what data item is present
            for (int FSPEC_Index = 1; FSPEC_Index <= FSPEC_Length; FSPEC_Index++)
            {
                switch (FSPEC_Index)
                {
                case 1:

                    // 010 Data Source Identifier
                    if (FourFSPECOctets[Bit_Ops.Bit7] == true)
                    {
                        DataOut = DataOut + "  010:T";
                        I063DataItems[ItemIDToIndex("010")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  010:F";
                    }

                    //  015, Service Identification
                    if (FourFSPECOctets[Bit_Ops.Bit6] == true)
                    {
                        DataOut = DataOut + "  015:T";
                        I063DataItems[ItemIDToIndex("015")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  015:F";
                    }

                    //  030, Time of Message
                    if (FourFSPECOctets[Bit_Ops.Bit5] == true)
                    {
                        DataOut = DataOut + "  030:T";
                        I063DataItems[ItemIDToIndex("030")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  030:F";
                    }

                    //  050, Sensor Identifier
                    if (FourFSPECOctets[Bit_Ops.Bit4] == true)
                    {
                        DataOut = DataOut + "  050:T";
                        I063DataItems[ItemIDToIndex("050")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  050:F";
                    }

                    //  060, Sensor Configuration and Status
                    if (FourFSPECOctets[Bit_Ops.Bit3] == true)
                    {
                        DataOut = DataOut + "  060:T";
                        I063DataItems[ItemIDToIndex("060")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  060:F";
                    }

                    //  070, Time Stamping Bias
                    if (FourFSPECOctets[Bit_Ops.Bit2] == true)
                    {
                        DataOut = DataOut + "  070:T";
                        I063DataItems[ItemIDToIndex("070")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  070:F";
                    }

                    //  080, SSR / Mode S Range Gain and Bias
                    if (FourFSPECOctets[Bit_Ops.Bit1] == true)
                    {
                        DataOut = DataOut + "  080:T";
                        I063DataItems[ItemIDToIndex("080")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  080:F";
                    }

                    break;

                case 2:

                    //  081, SSR / Mode S Azimuth Bias
                    if (FourFSPECOctets[Bit_Ops.Bit15] == true)
                    {
                        DataOut = DataOut + "  081:T";
                        I063DataItems[ItemIDToIndex("081")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  081:F";
                    }

                    //  090, PSR Range Gain and Bias
                    if (FourFSPECOctets[Bit_Ops.Bit14] == true)
                    {
                        DataOut = DataOut + "  090:T";
                        I063DataItems[ItemIDToIndex("090")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  090:F";
                    }

                    //  091, PSR Azimuth Bias
                    if (FourFSPECOctets[Bit_Ops.Bit13] == true)
                    {
                        DataOut = DataOut + "  091:T";
                        I063DataItems[ItemIDToIndex("091")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  091:F";
                    }

                    //  092, PSR Elevation Bias
                    if (FourFSPECOctets[Bit_Ops.Bit12] == true)
                    {
                        DataOut = DataOut + "  092:T";
                        I063DataItems[ItemIDToIndex("092")].IsPresent = true;
                    }
                    else
                    {
                        DataOut = DataOut + "  092:F";
                    }

                    // Spare
                    if (FourFSPECOctets[Bit_Ops.Bit11] == true)
                    {
                        DataOut = DataOut + "  SPR:T";
                    }
                    else
                    {
                        DataOut = DataOut + "  SPR:F";
                    }

                    // RE Reserved Expansion Field
                    if (FourFSPECOctets[Bit_Ops.Bit10] == true)
                    {
                        DataOut = DataOut + "  RES:T";
                    }
                    else
                    {
                        DataOut = DataOut + "  RES:F";
                    }

                    // SP Special Purpose Field
                    if (FourFSPECOctets[Bit_Ops.Bit9] == true)
                    {
                        DataOut = DataOut + "  SPF:T";
                    }
                    else
                    {
                        DataOut = DataOut + "  SPF:F";
                    }

                    break;

                // Handle errors
                default:
                    DataOut = DataOut + "  UKN:T";
                    break;
                }

                CAT63DecodeAndStore.Do(Data);
            }

            // Return decoded data
            return(DataOut);
        }
Example #9
0
        public string[] Decode(byte[] DataBlockBuffer, string Time, out int NumOfMessagesDecoded)
        {
            // Define output data buffer
            string[] DataOut = new string[3000];

            // Determine the size of the datablock
            int LengthOfDataBlockInBytes = DataBlockBuffer.Length;

            // Index into the array of record strings
            int DataOutIndex = 0;

            // Reset buffer indexes
            CurrentDataBufferOctalIndex = 0;
            int DataBufferIndexForThisExtraction = 0;

            // Determine SIC/SAC Index
            int SIC_Index = 0;
            int SAC_Index = 0;

            // Lenght of the current record's FSPECs
            int FSPEC_Length = 0;

            // Creates and initializes a BitVector32 with all bit flags set to FALSE.
            BitVector32 FourFSPECOctets = new BitVector32();

            while (DataBufferIndexForThisExtraction < LengthOfDataBlockInBytes)
            {
                // Assume that there will be no more than 1000 bytes in one record
                byte[] LocalSingleRecordBuffer = new byte[3000];

                Array.Copy(DataBlockBuffer, DataBufferIndexForThisExtraction, LocalSingleRecordBuffer, 0, (LengthOfDataBlockInBytes - DataBufferIndexForThisExtraction));

                // Get all four data words, but use only the number specifed
                // by the length of FSPEC words
                FourFSPECOctets = ASTERIX.GetFourFSPECOctets(LocalSingleRecordBuffer);

                // Determine Length of FSPEC fields in bytes
                FSPEC_Length = ASTERIX.DetermineLenghtOfFSPEC(LocalSingleRecordBuffer);

                // Check wether 010 is present
                if (FourFSPECOctets[Bit_Ops.Bit7] == true)
                {
                    // Determine SIC/SAC Index
                    SIC_Index = FSPEC_Length;
                    SAC_Index = SIC_Index + 1;

                    // Extract SIC/SAC Indexes.
                    DataOut[DataOutIndex] = LocalSingleRecordBuffer[SIC_Index].ToString() + '/' + LocalSingleRecordBuffer[SAC_Index].ToString();

                    // Save of the current data buffer index so it can be used by
                    // Decoder
                    CurrentDataBufferOctalIndex = SAC_Index + 1;
                }
                else
                {
                    // Extract SIC/SAC Indexes.
                    DataOut[DataOutIndex] = "---" + '/' + "---";
                }

                ///////////////////////////////////////////////////////////////////////////
                // Populate the current SIC/SAC and Time stamp for this meesage
                //
                I002DataItems[ItemIDToIndex("010")].value =
                    new ASTERIX.SIC_SAC_Time(LocalSingleRecordBuffer[SIC_Index], LocalSingleRecordBuffer[SAC_Index], ASTERIX.TimeOfReception);

                // Loop for each FSPEC and determine what data item is present
                for (int FSPEC_Index = 1; FSPEC_Index <= FSPEC_Length; FSPEC_Index++)
                {
                    switch (FSPEC_Index)
                    {
                    case 1:

                        // 010 Data Source Identifier
                        if (FourFSPECOctets[Bit_Ops.Bit7] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  010:T";
                            I002DataItems[ItemIDToIndex("010")].HasBeenPresent   = true;
                            I002DataItems[ItemIDToIndex("010")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  010:F";
                            I002DataItems[ItemIDToIndex("010")].CurrentlyPresent = false;
                        }

                        // 000 Message Type
                        if (FourFSPECOctets[Bit_Ops.Bit6] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  000:T";
                            I002DataItems[ItemIDToIndex("000")].HasBeenPresent   = true;
                            I002DataItems[ItemIDToIndex("000")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  000:F";
                            I002DataItems[ItemIDToIndex("000")].CurrentlyPresent = false;
                        }

                        // 020 Sector Number
                        if (FourFSPECOctets[Bit_Ops.Bit5] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  020:T";
                            I002DataItems[ItemIDToIndex("020")].HasBeenPresent   = true;
                            I002DataItems[ItemIDToIndex("020")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  020:F";
                            I002DataItems[ItemIDToIndex("020")].CurrentlyPresent = false;
                        }

                        // 030 Time of Day
                        if (FourFSPECOctets[Bit_Ops.Bit4] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  030:T";
                            I002DataItems[ItemIDToIndex("030")].HasBeenPresent   = true;
                            I002DataItems[ItemIDToIndex("030")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  030:F";
                            I002DataItems[ItemIDToIndex("030")].CurrentlyPresent = false;
                        }

                        // 041 Antenna Rotation Period
                        if (FourFSPECOctets[Bit_Ops.Bit3] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  041:T";
                            I002DataItems[ItemIDToIndex("041")].HasBeenPresent   = true;
                            I002DataItems[ItemIDToIndex("041")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  041:F";
                            I002DataItems[ItemIDToIndex("041")].CurrentlyPresent = false;
                        }

                        // 050 Station Configuration Status
                        if (FourFSPECOctets[Bit_Ops.Bit2] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  050:T";
                            I002DataItems[ItemIDToIndex("050")].HasBeenPresent   = true;
                            I002DataItems[ItemIDToIndex("050")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  050:F";
                            I002DataItems[ItemIDToIndex("050")].CurrentlyPresent = false;
                        }

                        // 060 Station Processing Mode
                        if (FourFSPECOctets[Bit_Ops.Bit1] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  060:T";
                            I002DataItems[ItemIDToIndex("060")].HasBeenPresent   = true;
                            I002DataItems[ItemIDToIndex("060")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  060:F";
                            I002DataItems[ItemIDToIndex("060")].CurrentlyPresent = false;
                        }
                        break;

                    case 2:

                        // 070 Plot Count Values
                        if (FourFSPECOctets[Bit_Ops.Bit15] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  070:T";
                            I002DataItems[ItemIDToIndex("070")].HasBeenPresent   = true;
                            I002DataItems[ItemIDToIndex("070")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  070:F";
                            I002DataItems[ItemIDToIndex("070")].CurrentlyPresent = false;
                        }

                        // 100 Dynamic Window - Type 1
                        if (FourFSPECOctets[Bit_Ops.Bit14] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  100:T";
                            I002DataItems[ItemIDToIndex("100")].HasBeenPresent   = true;
                            I002DataItems[ItemIDToIndex("100")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  100:F";
                            I002DataItems[ItemIDToIndex("100")].CurrentlyPresent = false;
                        }

                        // 090 Collimation Error
                        if (FourFSPECOctets[Bit_Ops.Bit13] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  090:T";
                            I002DataItems[ItemIDToIndex("090")].HasBeenPresent   = true;
                            I002DataItems[ItemIDToIndex("090")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  090:F";
                            I002DataItems[ItemIDToIndex("090")].CurrentlyPresent = false;
                        }

                        // 080 Warning/Error Conditions
                        if (FourFSPECOctets[Bit_Ops.Bit12] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  080:T";
                            I002DataItems[ItemIDToIndex("080")].HasBeenPresent   = true;
                            I002DataItems[ItemIDToIndex("080")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  080:F";
                            I002DataItems[ItemIDToIndex("080")].CurrentlyPresent = false;
                        }

                        break;

                    // Handle errors
                    default:
                        DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  UKN:T";
                        break;
                    }
                }

                DataOutIndex++;
                CAT02DecodeAndStore.Do(LocalSingleRecordBuffer);
                DataBufferIndexForThisExtraction = DataBufferIndexForThisExtraction + CurrentDataBufferOctalIndex + 1;
            }

            // Return decoded data
            NumOfMessagesDecoded = DataOutIndex;
            return(DataOut);
        }
Example #10
0
        private void SetInputConnectionToReplayParameters()
        {
            bool      Input_Validated = true;
            IPAddress IP         = IPAddress.Any;
            IPAddress Multicast  = IPAddress.Any;
            int       PortNumber = 2222;


            // First make sure that all boxes are filled out
            if ((!string.IsNullOrEmpty(this.txtboxIPAddress.Text)) &&
                (!string.IsNullOrEmpty(this.comboBoxNetworkInterface.Text)) &&
                (!string.IsNullOrEmpty(this.textboxPort.Text)))
            {
                // Validate that a valid IP address is entered
                if ((IPAddress.TryParse(this.txtboxIPAddress.Text, out Multicast) != true) || (IPAddress.TryParse(this.comboBoxNetworkInterface.Text, out IP) != true))
                {
                    MessageBox.Show("Not a valid IP address");
                    Input_Validated = false;
                }
                else // Add a check that this is a valid multicast address
                {
                    UdpClient TempSock;
                    TempSock = new UdpClient(2222);// Port does not matter
                    // Open up a new socket with the net IP address and port number
                    try
                    {
                        TempSock.JoinMulticastGroup(Multicast, 50); // 50 is TTL value
                    }
                    catch
                    {
                        MessageBox.Show("Not valid Multicast address (has to be in range 224.0.0.0 to 239.255.255.255");
                        Input_Validated = false;
                    }
                    if (TempSock != null)
                    {
                        TempSock.Close();
                    }
                }

                if (int.TryParse(this.textboxPort.Text, out PortNumber) && (PortNumber >= 1 && PortNumber <= 65535))
                {
                }
                else
                {
                    MessageBox.Show("Invalid Port number");
                    Input_Validated = false;
                }
            }
            else
            {
                MessageBox.Show("Please fill out all data fileds");
                Input_Validated = false;
            }


            // Input has been validated, so lets connect to the provided multicast address and interface
            if (Input_Validated == true)
            {
                // Syntatically all the provided data is valid, so save it off so it persists over the sessions
                Properties.Settings.Default.ReplayMulticast = this.txtboxIPAddress.Text;
                Properties.Settings.Default.ReplayPort      = this.textboxPort.Text;
                Properties.Settings.Default.Save();

                SharedData.ConnName = "Loc Replay";
                SharedData.CurrentInterfaceIPAddress = this.comboBoxNetworkInterface.Text;
                SharedData.CurrentMulticastAddress   = this.txtboxIPAddress.Text;
                SharedData.Current_Port = int.Parse(this.textboxPort.Text);

                if (ASTERIX.ReinitializeSocket() != true)
                {
                    SharedData.ResetConnectionParameters();
                }
            }
        }
        private static void ExtractAndDecodeASTERIX_CAT_DataBlock(byte[] DataBlock, bool Is_Live_Data)
        {
            // First thing is to store the time of the reception regardless of the category received
            string Time = DateTime.Now.Hour.ToString().PadLeft(2, '0') + ":" + DateTime.Now.Minute.ToString().PadLeft(2, '0') + ":" +
                          DateTime.Now.Second.ToString().PadLeft(2, '0') + ":" + DateTime.Now.Millisecond.ToString().PadLeft(3, '0');

            // Save off the time of reception so decoders can use it
            TimeOfReception = DateTime.Now;

            // Extract ASTERIX category
            string Category = ASTERIX.ExtractCategory(DataBlock);

            // Extract lenght in Bytes, as indicated by the ASTERIX
            string LengthOfDataBlockInBytes = ASTERIX.ExtractLengthOfDataBlockInBytes(DataBlock);

            // Here format the lenght of bytes
            // to always use 3 characters for better alignement
            if (LengthOfDataBlockInBytes.Length < 3)
            {
                LengthOfDataBlockInBytes = "0" + LengthOfDataBlockInBytes;
            }
            else if (LengthOfDataBlockInBytes.Length < 2)
            {
                LengthOfDataBlockInBytes = "00" + LengthOfDataBlockInBytes;
            }

            // Define a string to store data not specific for all messages and add commond data
            // 1. TIME of reception
            // 2. Source IP address
            // 3. Multicast IP address
            // 4. Length of data block in bytes
            // 5. Asterix Category
            //
            // 6. Append Category specifc data, done just below

            string Common_Message_Data_String;

            if (Is_Live_Data == true)
            {
                Common_Message_Data_String = Time + "     " + iep.ToString() + "        " + SharedData.CurrentMulticastAddress + ':' + SharedData.Current_Port.ToString() + "             " + LengthOfDataBlockInBytes.ToString() + "        " + Category + "           ";
            }
            else
            {
                Common_Message_Data_String = Time + "     " + "Recorded" + "        " + "Recorded" + ':' + "Recorded" + "             " + LengthOfDataBlockInBytes.ToString() + "        " + Category + "           ";
            }
            // Hold individual records of the messages
            // from an individual data block
            string[] MessageData = new string[3000];

            byte[] DataBlockNoCATandLEN = new byte[DataBlock.Length - 3];

            // Now after we extracted Category and Lenght of the Data Block lets remove the first three octets from the data
            // buffer and pass it on to individual message handlers to do message decoding
            Array.Copy(DataBlock, 3, DataBlockNoCATandLEN, 0, (DataBlock.Length - 3));

            DataBlock = DataBlockNoCATandLEN;

            // Now do a switch based on the category received
            int NumOfMsgsDecoded = 0;

            switch (Category)
            {
            // Monoradar Data Target Reports, from a Radar Surveillance System to an SDPS
            // (plots and tracks from PSRs, SSRs, MSSRs, excluding Mode S and ground surveillance)
            case "001":
                if (Properties.Settings.Default.CAT_001_Enabled == true)
                {
                    CAT01 MyCAT01 = new CAT01();
                    MessageData = MyCAT01.Decode(DataBlock, Time, out NumOfMsgsDecoded);
                }
                break;

            // Monoradar Service Messages (status, North marker, sector crossing messages)
            case "002":
                if (Properties.Settings.Default.CAT_002_Enabled == true)
                {
                    CAT02 MyCAT02 = new CAT02();
                    MessageData = MyCAT02.Decode(DataBlock, Time, out NumOfMsgsDecoded);
                }
                break;

            // Monoradar Derived Weather Information
            case "008":
                if (Properties.Settings.Default.CAT_008_Enabled == true)
                {
                    CAT08 MyCAT08 = new CAT08();
                }
                break;

            // Next version of Category 002: PSR Radar, M-SSR Radar, Mode-S Station
            case "034":
                if (Properties.Settings.Default.CAT_034_Enabled == true)
                {
                    CAT34 MyCAT34 = new CAT34();
                    MessageData = MyCAT34.Decode(DataBlock, Time, out NumOfMsgsDecoded);
                }
                break;

            // Next version of Category 001: PSR Radar, M-SSR Radar, Mode-S Station
            case "048":
                if (Properties.Settings.Default.CAT_048_Enabled == true)
                {
                    CAT48 MyCAT48 = new CAT48();
                    MessageData = MyCAT48.Decode(DataBlock, Time, out NumOfMsgsDecoded);
                }
                break;

            // System Track Data(next version of Category 030 & 011, also applicable to non-ARTAS systems)
            case "062":
                if (Properties.Settings.Default.CAT_062_Enabled == true)
                {
                    CAT62 MyCAT62 = new CAT62();
                    MessageData = MyCAT62.Decode(DataBlock, Time, out NumOfMsgsDecoded);
                }
                break;

            // Sensor Status Messages (SPDS)
            case "063":
                if (Properties.Settings.Default.CAT_063_Enabled == true)
                {
                    CAT63 MyCAT63 = new CAT63();
                }
                break;

            // SDPS Service Status Messages (SDPS)
            case "065":
                if (Properties.Settings.Default.CAT_065_Enabled == true)
                {
                    CAT65 MyCAT65 = new CAT65();
                }
                break;

            // Transmission of Reference Trajectory State Vectors
            case "244":
                if (Properties.Settings.Default.CAT_244_Enabled == true)
                {
                    CAT244 MyCAT244 = new CAT244();
                }
                break;

            // Handle unsupported data/categories
            default:
                Common_Message_Data_String = Common_Message_Data_String + " Unsupported category " + Category + " has been received";
                break;
            }

            if (Properties.Settings.Default.PopulateMainListBox == true)
            {
                for (int I = 0; I < NumOfMsgsDecoded; I++)
                {
                    SharedData.DataBox.Items.Add(Common_Message_Data_String + MessageData[I]);
                }
            }
        }
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // The method that gets invoked as a thread when a Connect button is
        // pressed. It will listen on a given multicast address and store messages in the
        // list box above.
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
        public static void ListenForData()
        {
            bool ThereWasAnException = false;

            // File stream
            // Stream RecordingStream_debug = new FileStream(@"C:\ASTERIX\Italy", FileMode.Create);
            //BinaryWriter RecordingBinaryWriter_debug = new BinaryWriter(RecordingStream_debug);

            // Loop forever
            while (!_shouldStop)
            {
                // Do something only if user has requested so
                if (SharedData.bool_Listen_for_Data)
                {
                    ThereWasAnException = false;
                    try
                    {
                        // Lets receive data in an array of bytes
                        // (an octet, of course composed of 8bits)
                        UDPBuffer = sock.Receive(ref iep);
                        LastDataBlockDateTimeForStalleData = DateTime.Now;
                    }
                    catch
                    {
                        ThereWasAnException = true;
                    }

                    if (ThereWasAnException == false)
                    {
                        int DataBufferIndexForThisExtraction = 0;

                        // Check if this is non-standard 6 byte RMCDE header ASTERIX.
                        if (Properties.Settings.Default.RMCDE_ASTERIX)
                        {
                            UDPBuffer_Non_Standard = new byte[(UDPBuffer.Length - 6)];
                            Array.Copy(UDPBuffer, 6, UDPBuffer_Non_Standard, 0, (UDPBuffer.Length - 6));
                            UDPBuffer = UDPBuffer_Non_Standard;
                        }

                        // Now write the data block
                        //RecordingBinaryWriter_debug.Write(UDPBuffer);

                        // Extract lenghts
                        int LengthOfASTERIX_CAT = ASTERIX.ExtractLengthOfDataBlockInBytes_Int(UDPBuffer);
                        int LenghtOfDataBuffer  = UDPBuffer.Length;

                        // Loop through the buffer and pass on each ASTERIX category block to
                        // the category extractor. The extractor itslef will then extract individual
                        // data records.
                        try
                        {
                            while (DataBufferIndexForThisExtraction < LenghtOfDataBuffer)
                            {
                                byte[] LocalSingle_ASTERIX_CAT_Buffer = new byte[LengthOfASTERIX_CAT];
                                Array.Copy(UDPBuffer, DataBufferIndexForThisExtraction, LocalSingle_ASTERIX_CAT_Buffer, 0, LengthOfASTERIX_CAT);
                                ExtractAndDecodeASTERIX_CAT_DataBlock(LocalSingle_ASTERIX_CAT_Buffer, true);

                                DataBufferIndexForThisExtraction = DataBufferIndexForThisExtraction + LengthOfASTERIX_CAT;

                                if (DataBufferIndexForThisExtraction < LenghtOfDataBuffer)
                                {
                                    Array.Copy(UDPBuffer, DataBufferIndexForThisExtraction, LocalSingle_ASTERIX_CAT_Buffer, 0, 3);
                                    LengthOfASTERIX_CAT = ASTERIX.ExtractLengthOfDataBlockInBytes_Int(LocalSingle_ASTERIX_CAT_Buffer);
                                }
                            }
                        }
                        catch
                        {
                            MessageBox.Show("There was an error in data acquire, please check if standard ASTERIX or RMCDE header is properly selected.");
                        }

                        // Check if recording of the currently live connection is requested
                        if (SharedData.DataRecordingClass.DataRecordingRequested == true)
                        {
                            if (RecordingJustStarted == true)
                            {
                                RecordingJustStarted              = false;
                                RecordingStream                   = new FileStream(SharedData.DataRecordingClass.FilePathandName, FileMode.Create);
                                RecordingBinaryWriter             = new BinaryWriter(RecordingStream);
                                LastDataBlockDateTimeForRecording = DateTime.Now;
                            }

                            // Determine the type of the recording
                            if (Properties.Settings.Default.RecordActiveInRaw == true)
                            {
                                // Just record in the raw format with not headers added
                                RecordingBinaryWriter.Write(UDPBuffer);
                            }
                            else // Here add headers
                            {
                                TimeSpan TimeDiff = DateTime.Now - LastDataBlockDateTimeForRecording;
                                LastDataBlockDateTimeForRecording = DateTime.Now;
                                // Header 1: Size of the original data block
                                // Header 2: The time between two data blocks (current and the last one)
                                //-----------------------------------------------------------------------
                                // Header 1 // Header 2
                                // ----------------------------------------------------------------------
                                // 4 bytes  // 4 bytes
                                // First add the size of the data block, not including the two headers

                                // Block size
                                RecordingBinaryWriter.Write(UDPBuffer.Length);
                                // Time between last and this block
                                RecordingBinaryWriter.Write(TimeDiff.Milliseconds);
                                // Now write the data block
                                RecordingBinaryWriter.Write(UDPBuffer);
                            }
                        }
                        else if (RecordingJustStarted == false)
                        {
                            RecordingJustStarted = true;
                            // Close the data stream
                            if (RecordingBinaryWriter != null)
                            {
                                RecordingBinaryWriter.Close();
                            }
                            if (RecordingStream != null)
                            {
                                RecordingStream.Close();
                            }
                        }
                    }
                }
            }

            _shouldStop = false;
        }
Example #13
0
        public string[] Decode(byte[] DataBlockBuffer, string Time, out int NumOfMessagesDecoded)
        {
            // Define output data buffer
            string[] DataOut = new string[2000];

            // Determine the size of the datablock
            int LengthOfDataBlockInBytes = DataBlockBuffer.Length;

            // Index into the array of record strings
            int DataOutIndex = 0;

            // Reset buffer indexes
            CurrentDataBufferOctalIndex = 0;
            int DataBufferIndexForThisExtraction = 0;

            // SIC/SAC Indexes
            int SIC_Index = 0;
            int SAC_Index = 0;

            // Lenght of the current record's FSPECs
            int FSPEC_Length = 0;

            // The first four possible FSPEC octets
            BitVector32 FourFSPECOctets = new BitVector32();

            // The fifth FSPEC octet in the case RE or SP field is present
            BitVector32 TheFifthFSPECOctet = new BitVector32();

            while (DataBufferIndexForThisExtraction < LengthOfDataBlockInBytes)
            {
                // Assume that there will be no more than 200 bytes in one record
                byte[] LocalSingleRecordBuffer = new byte[3000];

                Array.Copy(DataBlockBuffer, DataBufferIndexForThisExtraction, LocalSingleRecordBuffer, 0, (LengthOfDataBlockInBytes - DataBufferIndexForThisExtraction));

                // Get all four data words, but use only the number specifed
                // by the length of FSPEC words
                FourFSPECOctets    = ASTERIX.GetFourFSPECOctets(LocalSingleRecordBuffer);
                TheFifthFSPECOctet = ASTERIX.GetFifthFSPECOctet(LocalSingleRecordBuffer);

                // Determine Length of FSPEC fields in bytes
                FSPEC_Length = ASTERIX.DetermineLenghtOfFSPEC(LocalSingleRecordBuffer);

                // Check wether 010 is present
                if (FourFSPECOctets[Bit_Ops.Bit7] == true)
                {
                    // Determine SIC/SAC Index
                    SIC_Index = FSPEC_Length;
                    SAC_Index = SIC_Index + 1;

                    // Extract SIC/SAC Indexes.
                    DataOut[DataOutIndex] = LocalSingleRecordBuffer[SIC_Index].ToString() + '/' + LocalSingleRecordBuffer[SAC_Index].ToString();

                    // Save of the current data buffer index so it can be used by
                    // Decoder
                    CurrentDataBufferOctalIndex = SAC_Index + 1;
                }
                else
                {
                    // Extract SIC/SAC Indexes.
                    DataOut[DataOutIndex] = "---" + '/' + "---";
                }

                ///////////////////////////////////////////////////////////////////////////
                // Populate the current SIC/SAC and Time stamp for this meesage
                //
                I062DataItems[ItemIDToIndex("010")].value =
                    new ASTERIX.SIC_SAC_Time(LocalSingleRecordBuffer[SIC_Index], LocalSingleRecordBuffer[SAC_Index], ASTERIX.TimeOfReception);

                // Loop for each FSPEC and determine what data item is present
                for (int FSPEC_Index = 1; FSPEC_Index <= FSPEC_Length; FSPEC_Index++)
                {
                    switch (FSPEC_Index)
                    {
                    case 1:

                        // 010 Data Source Identifier
                        if (FourFSPECOctets[Bit_Ops.Bit7] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  010:T";
                            I062DataItems[ItemIDToIndex("010")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("010")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  010:F";
                            I062DataItems[ItemIDToIndex("010")].CurrentlyPresent = false;
                        }

                        // Spare bit
                        if (FourFSPECOctets[Bit_Ops.Bit6] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  SPR:T";
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  SPR:F";
                        }

                        // 015 Service Identification
                        if (FourFSPECOctets[Bit_Ops.Bit5] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  015:T";
                            I062DataItems[ItemIDToIndex("015")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("015")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  015:F";
                            I062DataItems[ItemIDToIndex("015")].CurrentlyPresent = false;
                        }

                        // 070 Time Of Track Information
                        if (FourFSPECOctets[Bit_Ops.Bit4] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  070:T";
                            I062DataItems[ItemIDToIndex("070")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("070")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  070:F";
                            I062DataItems[ItemIDToIndex("070")].CurrentlyPresent = false;
                        }

                        // 105 Calculated Track Position (WGS-84)
                        if (FourFSPECOctets[Bit_Ops.Bit3] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  105:T";
                            I062DataItems[ItemIDToIndex("105")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("105")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  105:F";
                            I062DataItems[ItemIDToIndex("105")].CurrentlyPresent = false;
                        }

                        // 100 Calculated Track Position (Cartesian)
                        if (FourFSPECOctets[Bit_Ops.Bit2] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  100:T";
                            I062DataItems[ItemIDToIndex("100")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("100")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  100:F";
                            I062DataItems[ItemIDToIndex("100")].CurrentlyPresent = false;
                        }

                        // 185 Calculated Track Velocity (Cartesian)
                        if (FourFSPECOctets[Bit_Ops.Bit1] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  185:T";
                            I062DataItems[ItemIDToIndex("185")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("185")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  185:F";
                            I062DataItems[ItemIDToIndex("185")].CurrentlyPresent = false;
                        }

                        break;

                    case 2:

                        // 210 Calculated Acceleration (Cartesian)
                        if (FourFSPECOctets[Bit_Ops.Bit15] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  210:T";
                            I062DataItems[ItemIDToIndex("210")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("210")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  210:F";
                            I062DataItems[ItemIDToIndex("210")].CurrentlyPresent = false;
                        }

                        // 060 Track Mode 3/A Code
                        if (FourFSPECOctets[Bit_Ops.Bit14] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  060:T";
                            I062DataItems[ItemIDToIndex("060")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("060")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  060:F";
                            I062DataItems[ItemIDToIndex("060")].CurrentlyPresent = false;
                        }

                        // 245 Target Identification
                        if (FourFSPECOctets[Bit_Ops.Bit13] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  245:T";
                            I062DataItems[ItemIDToIndex("245")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("245")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  245:F";
                            I062DataItems[ItemIDToIndex("245")].CurrentlyPresent = false;
                        }

                        // 380 Aircraft Derived Data
                        if (FourFSPECOctets[Bit_Ops.Bit12] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  380:T";
                            I062DataItems[ItemIDToIndex("380")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("380")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  380:F";
                            I062DataItems[ItemIDToIndex("380")].CurrentlyPresent = false;
                        }

                        // 040 Track Number
                        if (FourFSPECOctets[Bit_Ops.Bit11] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  040:T";
                            I062DataItems[ItemIDToIndex("040")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("040")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  040:F";
                            I062DataItems[ItemIDToIndex("040")].CurrentlyPresent = false;
                        }

                        // 080 Track Status
                        if (FourFSPECOctets[Bit_Ops.Bit10] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  080:T";
                            I062DataItems[ItemIDToIndex("080")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("080")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  080:F";
                            I062DataItems[ItemIDToIndex("080")].CurrentlyPresent = false;
                        }

                        // 290 System Track Update Ages
                        if (FourFSPECOctets[Bit_Ops.Bit9] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  290:T";
                            I062DataItems[ItemIDToIndex("290")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("290")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  290:F";
                            I062DataItems[ItemIDToIndex("290")].CurrentlyPresent = false;
                        }

                        break;

                    case 3:

                        // 200 Mode of Movement
                        if (FourFSPECOctets[Bit_Ops.Bit23] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  200:T";
                            I062DataItems[ItemIDToIndex("200")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("200")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  200:F";
                            I062DataItems[ItemIDToIndex("200")].CurrentlyPresent = false;
                        }

                        // 295 Track Data Ages
                        if (FourFSPECOctets[Bit_Ops.Bit22] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  295:T";
                            I062DataItems[ItemIDToIndex("295")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("295")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  295:F";
                            I062DataItems[ItemIDToIndex("295")].CurrentlyPresent = false;
                        }

                        // 136 Measured Flight Level
                        if (FourFSPECOctets[Bit_Ops.Bit21] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  136:T";
                            I062DataItems[ItemIDToIndex("136")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("136")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  136:F";
                            I062DataItems[ItemIDToIndex("136")].CurrentlyPresent = false;
                        }

                        // 130 Calculated Track Geometric Altitude
                        if (FourFSPECOctets[Bit_Ops.Bit20] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  130:T";
                            I062DataItems[ItemIDToIndex("130")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("130")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  130:F";
                            I062DataItems[ItemIDToIndex("130")].CurrentlyPresent = false;
                        }

                        // 135 Calculated Track Barometric Altitude
                        if (FourFSPECOctets[Bit_Ops.Bit19] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  135:T";
                            I062DataItems[ItemIDToIndex("135")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("135")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  135:F";
                            I062DataItems[ItemIDToIndex("135")].CurrentlyPresent = false;
                        }

                        // 220 Calculated Rate Of Climb/Descent
                        if (FourFSPECOctets[Bit_Ops.Bit18] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  220:T";
                            I062DataItems[ItemIDToIndex("220")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("220")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  220:F";
                            I062DataItems[ItemIDToIndex("220")].CurrentlyPresent = false;
                        }


                        // 390 Flight Plan Related Data
                        if (FourFSPECOctets[Bit_Ops.Bit17] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  390:T";
                            I062DataItems[ItemIDToIndex("390")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("390")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  390:F";
                            I062DataItems[ItemIDToIndex("390")].CurrentlyPresent = false;
                        }

                        break;


                    case 4:

                        // 270 Target Size & Orientation
                        if (FourFSPECOctets[Bit_Ops.Bit31] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  270:T";
                            I062DataItems[ItemIDToIndex("270")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("270")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  270:F";
                            I062DataItems[ItemIDToIndex("270")].CurrentlyPresent = false;
                        }

                        // 300 Vehicle Fleet Identification
                        if (FourFSPECOctets[Bit_Ops.Bit30] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  300:T";
                            I062DataItems[ItemIDToIndex("300")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("300")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  300:F";
                            I062DataItems[ItemIDToIndex("300")].CurrentlyPresent = false;
                        }

                        // 110 Mode 5 Data reports & Extended Mode 1 Code
                        if (FourFSPECOctets[Bit_Ops.Bit29] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  110:T";
                            I062DataItems[ItemIDToIndex("110")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("110")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  110:F";
                            I062DataItems[ItemIDToIndex("110")].CurrentlyPresent = false;
                        }

                        // 120 Track Mode 2 Code
                        if (FourFSPECOctets[Bit_Ops.Bit28] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  120:T";
                            I062DataItems[ItemIDToIndex("120")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("120")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  120:F";
                            I062DataItems[ItemIDToIndex("120")].CurrentlyPresent = false;
                        }

                        // 510 Composed Track Number
                        if (FourFSPECOctets[Bit_Ops.Bit27] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  510:T";
                            I062DataItems[ItemIDToIndex("510")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("510")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  510:F";
                            I062DataItems[ItemIDToIndex("510")].CurrentlyPresent = false;
                        }

                        // 500 Estimated Accuracies
                        if (FourFSPECOctets[Bit_Ops.Bit26] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  500:T";
                            I062DataItems[ItemIDToIndex("500")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("500")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  500:F";
                            I062DataItems[ItemIDToIndex("500")].CurrentlyPresent = false;
                        }

                        // 340 Measured Information
                        if (FourFSPECOctets[Bit_Ops.Bit25] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  340:T";
                            I062DataItems[ItemIDToIndex("340")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("340")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  340:F";
                            I062DataItems[ItemIDToIndex("340")].CurrentlyPresent = false;
                        }

                        break;

                    // These are Reserved Expansion and Special Purpose fileds.
                    case 5:

                        // RE Reserved Expansion Field
                        if (TheFifthFSPECOctet[Bit_Ops.Bit2] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  REF:T";
                            I062DataItems[ItemIDToIndex("REF")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("REF")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  REF:F";
                            I062DataItems[ItemIDToIndex("REF")].CurrentlyPresent = false;
                        }

                        // SP Special Purpose Indicator
                        if (TheFifthFSPECOctet[Bit_Ops.Bit1] == true)
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  SPI:T";
                            I062DataItems[ItemIDToIndex("SPI")].HasBeenPresent   = true;
                            I062DataItems[ItemIDToIndex("SPI")].CurrentlyPresent = true;
                        }
                        else
                        {
                            DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  SPI:F";
                            I062DataItems[ItemIDToIndex("SPI")].CurrentlyPresent = false;
                        }

                        break;

                    // Handle errors
                    default:
                        DataOut[DataOutIndex] = DataOut[DataOutIndex] + "  UKN:T";
                        break;
                    }
                }

                DataOutIndex++;
                CAT62DecodeAndStore.Do(LocalSingleRecordBuffer);
                DataBufferIndexForThisExtraction = DataBufferIndexForThisExtraction + CurrentDataBufferOctalIndex;
            }

            // Return decoded data
            NumOfMessagesDecoded = DataOutIndex;
            return(DataOut);
        }