AsterixDisplayAnalyser.CAT48.Decode C# (CSharp) Метод

Decode() публичный Метод

public Decode ( byte DataBlockBuffer, string Time, int &NumOfMessagesDecoded ) : string[]
DataBlockBuffer byte
Time string
NumOfMessagesDecoded int
Результат string[]
        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;
        }

Usage Example

        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]);
            }
        }
All Usage Examples Of AsterixDisplayAnalyser.CAT48::Decode