// 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); }
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"); }
// 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); }
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); }
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); }
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); }
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); }
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; }
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); }