Beispiel #1
0
        /// <summary>
        /// Decodes an airborne position message.
        /// </summary>
        /// <param name="message"></param>
        private void DecodeAirbornePosition(AdsbMessage message)
        {
            message.MessageFormat = message.Type == 0 ? MessageFormat.NoPositionInformation : MessageFormat.AirbornePosition;
            var subMessage = message.AirbornePosition = new AirbornePositionMessage();

            subMessage.SurveillanceStatus = (SurveillanceStatus)_BitStream.ReadByte(2);
            if (IsFineFormatTisb(message))
            {
                message.TisbIcaoModeAFlag = _BitStream.ReadByte(1);
            }
            else
            {
                if (message.Type == 0)
                {
                    _BitStream.Skip(1);
                }
                else
                {
                    subMessage.NicB = (byte)(_BitStream.ReadBit() ? 2 : 0);
                }
            }
            var rawAltitude = _BitStream.ReadUInt16(12);

            var acCode   = ((rawAltitude & 0xfe0) >> 1) | (rawAltitude & 0x0f);
            int?altitude = null;

            if ((rawAltitude & 0x10) != 0)
            {
                altitude = ModeSAltitudeConversion.CalculateBinaryAltitude(acCode);
            }
            else
            {
                altitude = ModeSAltitudeConversion.LookupGillhamAltitude(acCode);
            }
            if (message.Type < 20)
            {
                subMessage.BarometricAltitude = altitude;
            }
            else
            {
                subMessage.GeometricAltitude = altitude;
            }

            subMessage.PositionTimeIsExact = _BitStream.ReadBit();
            subMessage.CompactPosition     = ExtractCprCoordinate(message, 17);
        }
Beispiel #2
0
        /// <summary>
        /// See interface docs.
        /// </summary>
        /// <param name="rawMessage"></param>
        /// <param name="start"></param>
        /// <param name="signalLevel"></param>
        /// <param name="isMlat"></param>
        /// <returns></returns>
        public ModeSMessage Translate(byte[] rawMessage, int start, int?signalLevel, bool isMlat)
        {
            if (Statistics == null)
            {
                throw new InvalidOperationException("Statistics must be provided before Translate can do any work");
            }
            ModeSMessage result = null;

            var messageLength = rawMessage == null ? 0 : rawMessage.Length - start;

            if (messageLength > 6)
            {
                _BitStream.Initialise(rawMessage);
                _BitStream.Skip(start * 8);
                var downlinkFormatValue = _BitStream.ReadByte(5);
                if (downlinkFormatValue >= 24)
                {
                    downlinkFormatValue = 24;
                    _BitStream.Skip(-3);
                }

                bool isLongFrame = true;
                switch (downlinkFormatValue)
                {
                case 16:
                case 17:
                case 18:
                case 19:
                case 20:
                case 21:
                case 24:    if (messageLength > 13)
                    {
                        result = new ModeSMessage();
                    }
                    break;

                default:    isLongFrame = false; result = new ModeSMessage(); break;
                }

                if (result != null)
                {
                    result.SignalLevel    = signalLevel;
                    result.IsMlat         = isMlat;
                    result.DownlinkFormat = (DownlinkFormat)downlinkFormatValue;

                    switch (result.DownlinkFormat)
                    {
                    case DownlinkFormat.ShortAirToAirSurveillance:      DecodeShortAirToAirSurveillance(result); break;             // DF0

                    case DownlinkFormat.SurveillanceAltitudeReply:      DecodeSurveillanceAltitudeReply(result); break;             // DF4

                    case DownlinkFormat.SurveillanceIdentityReply:      DecodeSurveillanceIdentityReply(result); break;             // DF5

                    case DownlinkFormat.AllCallReply:                   DecodeAllCallReply(result); break;                          // DF11

                    case DownlinkFormat.LongAirToAirSurveillance:       DecodeLongAirToAirSurveillance(result); break;              // DF16

                    case DownlinkFormat.ExtendedSquitter:               DecodeExtendedSquitter(result); break;                      // DF17

                    case DownlinkFormat.ExtendedSquitterNonTransponder: DecodeExtendedSquitterNonTransponder(result); break;        // DF18

                    case DownlinkFormat.MilitaryExtendedSquitter:       DecodeMilitaryExtendedSquitter(result); break;              // DF19

                    case DownlinkFormat.CommBAltitudeReply:             DecodeCommBAltitudeReply(result); break;                    // DF20

                    case DownlinkFormat.CommBIdentityReply:             DecodeCommBIdentityReply(result); break;                    // DF21

                    case DownlinkFormat.CommD:                          DecodeCommD(result); break;                                 // DF24
                    }

                    if (Statistics != null)
                    {
                        Statistics.Lock(r => {
                            ++r.ModeSMessagesReceived;
                            ++r.ModeSDFStatistics[(int)result.DownlinkFormat].MessagesReceived;
                            if (isLongFrame)
                            {
                                ++r.ModeSLongFrameMessagesReceived;
                            }
                            else
                            {
                                ++r.ModeSShortFrameMessagesReceived;
                            }
                        });
                    }
                }
            }

            return(result);
        }
Beispiel #3
0
        public void BitStream_Skip_Jumps_Over_Bits_In_The_Stream()
        {
            var binary = "11001010001101011101001111110000";

            for (int i = 0; i < binary.Length; ++i)
            {
                var expectedBit = binary[i] == '1';

                _BitStream.Initialise(ParseBinary(binary));
                _BitStream.Skip(i);

                Assert.AreEqual(expectedBit, _BitStream.ReadBit(), "Expected {0} after skipping {1} bits, ReadBit returned {2}", expectedBit, i, !expectedBit);
            }
        }
        /// <summary>
        /// See interface docs.
        /// </summary>
        /// <param name="rawMessage"></param>
        /// <param name="start"></param>
        /// <returns></returns>
        public ModeSMessage Translate(byte[] rawMessage, int start)
        {
            ModeSMessage result = null;

            var messageLength = rawMessage == null ? 0 : rawMessage.Length - start;

            if (messageLength > 6)
            {
                _BitStream.Initialise(rawMessage);
                _BitStream.Skip(start * 8);
                var downlinkFormatValue = _BitStream.ReadByte(5);
                if (downlinkFormatValue >= 24)
                {
                    downlinkFormatValue = 24;
                    _BitStream.Skip(-3);
                }

                bool isLongFrame = true;
                switch (downlinkFormatValue)
                {
                case 16:
                case 17:
                case 18:
                case 19:
                case 20:
                case 21:
                case 24:    if (messageLength > 13)
                    {
                        result = new ModeSMessage();
                    }
                    break;

                default:    isLongFrame = false; result = new ModeSMessage(); break;
                }

                if (result != null)
                {
                    result.DownlinkFormat = (DownlinkFormat)downlinkFormatValue;

                    switch (result.DownlinkFormat)
                    {
                    case DownlinkFormat.ShortAirToAirSurveillance:      DecodeShortAirToAirSurveillance(result); break;             // DF0

                    case DownlinkFormat.SurveillanceAltitudeReply:      DecodeSurveillanceAltitudeReply(result); break;             // DF4

                    case DownlinkFormat.SurveillanceIdentityReply:      DecodeSurveillanceIdentityReply(result); break;             // DF5

                    case DownlinkFormat.AllCallReply:                   DecodeAllCallReply(result); break;                          // DF11

                    case DownlinkFormat.LongAirToAirSurveillance:       DecodeLongAirToAirSurveillance(result); break;              // DF16

                    case DownlinkFormat.ExtendedSquitter:               DecodeExtendedSquitter(result); break;                      // DF17

                    case DownlinkFormat.ExtendedSquitterNonTransponder: DecodeExtendedSquitterNonTransponder(result); break;        // DF18

                    case DownlinkFormat.MilitaryExtendedSquitter:       DecodeMilitaryExtendedSquitter(result); break;              // DF19

                    case DownlinkFormat.CommBAltitudeReply:             DecodeCommBAltitudeReply(result); break;                    // DF20

                    case DownlinkFormat.CommBIdentityReply:             DecodeCommBIdentityReply(result); break;                    // DF21

                    case DownlinkFormat.CommD:                          DecodeCommD(result); break;                                 // DF24
                    }

                    if (_Statistics.Lock != null)
                    {
                        lock (_Statistics.Lock) {
                            ++_Statistics.ModeSMessagesReceived;
                            ++_Statistics.ModeSDFCount[(int)result.DownlinkFormat];
                            if (isLongFrame)
                            {
                                ++_Statistics.ModeSLongFrameMessagesReceived;
                            }
                            else
                            {
                                ++_Statistics.ModeSShortFrameMessagesReceived;
                            }
                        }
                    }
                }
            }

            return(result);
        }