public void TestInitialise()
        {
            _OriginalClassFactory = Factory.TakeSnapshot();

            _HeartbeatService = TestUtilities.CreateMockSingleton<IHeartbeatService>();
            _StandingDataManager = TestUtilities.CreateMockSingleton<IStandingDataManager>();
            _StandingDataManager.Setup(r => r.FindCodeBlock(It.IsAny<string>())).Returns(new CodeBlock() { Country = "X" });
            _StandingDataManager.Setup(r => r.CodeBlocksLoaded).Returns(true);

            _Statistics = Factory.Singleton.Resolve<IStatistics>().Singleton;
            _Statistics.Initialise();
            _Statistics.ResetConnectionStatistics();
            _Statistics.ResetMessageCounters();

            _Translator = Factory.Singleton.Resolve<IRawMessageTranslator>();
            _Provider = new Mock<IRawMessageTranslatorProvider>() { DefaultValue = DefaultValue.Mock }.SetupAllProperties();
            _Provider.Setup(r => r.UtcNow).Returns(new DateTime(1999, 12, 31));
            _Translator.Provider = _Provider.Object;

            _PositionResetEvent = new EventRecorder<EventArgs<string>>();
            _Translator.PositionReset += _PositionResetEvent.Handler;

            _NowUtc = new DateTime(2012, 1, 2, 3, 4, 5, 6);
            _ModeSMessage = new ModeSMessage() { DownlinkFormat = DownlinkFormat.AllCallReply, Icao24 = 0x112233, ParityInterrogatorIdentifier = 0 };
            _AdsbMessage = new AdsbMessage(_ModeSMessage);

            _RandomIcaos = new List<int>();
        }
        public void TestInitialise()
        {
            _Statistics = Factory.Singleton.Resolve<IStatistics>().Singleton;
            _Statistics.Initialise();
            _Statistics.ResetMessageCounters();

            _Translator = Factory.Singleton.Resolve<IAdsbTranslator>();
            _ModeSMessage = new ModeSMessage();
        }
 public void ModeSMessageEventArgs_Constructor_Initialises_To_Known_State()
 {
     var dateTimeNow = DateTime.UtcNow;
     var message = new ModeSMessage();
     var adsbMessage = new AdsbMessage(message);
     var eventArgs = new ModeSMessageEventArgs(dateTimeNow, message, adsbMessage);
     Assert.AreEqual(dateTimeNow, eventArgs.ReceivedUtc);
     Assert.AreSame(message, eventArgs.ModeSMessage);
     Assert.AreSame(adsbMessage, eventArgs.AdsbMessage);
 }
        public void AdsbMessage_Constructor_Initialises_To_Known_Values_And_Properties_Work()
        {
            var modeSMessage = new ModeSMessage();
            var message = new AdsbMessage(modeSMessage);
            Assert.AreSame(modeSMessage, message.ModeSMessage);

            TestUtilities.TestProperty(message, m => m.AirbornePosition, null, new AirbornePositionMessage());
            TestUtilities.TestProperty(message, m => m.AirborneVelocity, null, new AirborneVelocityMessage());
            TestUtilities.TestProperty(message, m => m.IdentifierAndCategory, null, new IdentifierAndCategoryMessage());
            TestUtilities.TestProperty(message, m => m.MessageFormat, MessageFormat.None, MessageFormat.AircraftOperationalStatus);
            TestUtilities.TestProperty(message, m => m.SurfacePosition, null, new SurfacePositionMessage());
            TestUtilities.TestProperty(message, m => m.TargetStateAndStatus, null, new TargetStateAndStatusMessage());
            TestUtilities.TestProperty(message, m => m.Type, (byte)0, (byte)255);
            TestUtilities.TestProperty(message, m => m.AircraftStatus, null, new AircraftStatusMessage());
            TestUtilities.TestProperty(message, m => m.AircraftOperationalStatus, null, new AircraftOperationalStatusMessage());
        }
        public void TestInitialise()
        {
            _Statistics = Factory.Singleton.Resolve<IStatistics>().Singleton;
            _Statistics.Initialise();
            _Statistics.ResetConnectionStatistics();
            _Statistics.ResetMessageCounters();

            _OriginalClassFactory = Factory.TakeSnapshot();

            _RuntimeEnvironment = TestUtilities.CreateMockSingleton<IRuntimeEnvironment>();
            _RuntimeEnvironment.Setup(r => r.IsTest).Returns(true);

            _Port30003Translator = TestUtilities.CreateMockImplementation<IBaseStationMessageTranslator>();
            _ModeSTranslator = TestUtilities.CreateMockImplementation<IModeSTranslator>();
            _AdsbTranslator = TestUtilities.CreateMockImplementation<IAdsbTranslator>();
            _RawMessageTranslator = new Mock<IRawMessageTranslator>(MockBehavior.Default) { DefaultValue = DefaultValue.Mock };
            _ModeSParity = TestUtilities.CreateMockImplementation<IModeSParity>();
            _ModeSMessage = new ModeSMessage();
            _AdsbMessage = new AdsbMessage(_ModeSMessage);
            _Port30003Message = new BaseStationMessage();
            _Port30003Translator.Setup(r => r.Translate(It.IsAny<string>())).Returns(_Port30003Message);
            _AdsbTranslator.Setup(r => r.Translate(It.IsAny<ModeSMessage>())).Returns(_AdsbMessage);
            _ModeSTranslator.Setup(r => r.Translate(It.IsAny<byte[]>())).Returns(_ModeSMessage);
            _ModeSTranslator.Setup(r => r.Translate(It.IsAny<byte[]>(), It.IsAny<int>())).Returns(_ModeSMessage);
            _RawMessageTranslator.Setup(r => r.Translate(It.IsAny<DateTime>(), It.IsAny<ModeSMessage>(), It.IsAny<AdsbMessage>())).Returns(_Port30003Message);

            _Listener = Factory.Singleton.Resolve<IListener>();
            _Provider = new MockListenerProvider();
            _BytesExtractor = new MockMessageBytesExtractor();

            _ExceptionCaughtEvent = new EventRecorder<EventArgs<Exception>>();
            _ConnectionStateChangedEvent = new EventRecorder<EventArgs>();
            _ModeSMessageReceivedEvent = new EventRecorder<ModeSMessageEventArgs>();
            _Port30003MessageReceivedEvent = new EventRecorder<BaseStationMessageEventArgs>();
            _SourceChangedEvent = new EventRecorder<EventArgs>();

            _Listener.ConnectionStateChanged += _ConnectionStateChangedEvent.Handler;
            _Listener.ExceptionCaught += _ExceptionCaughtEvent.Handler;
            _Listener.ModeSMessageReceived += _ModeSMessageReceivedEvent.Handler;
            _Listener.Port30003MessageReceived += _Port30003MessageReceivedEvent.Handler;
            _Listener.SourceChanged += _SourceChangedEvent.Handler;

            _ExceptionCaughtEvent.EventRaised += DefaultExceptionCaughtHandler;
        }
 private void ExtractVerticalStatus(ModeSMessage reply)
 {
     reply.VerticalStatus = (VerticalStatus)_BitStream.ReadByte(1);
 }
 private void ExtractSensitivityLevel(ModeSMessage reply)
 {
     reply.SensitivityLevel = _BitStream.ReadByte(3);
 }
 private void ExtractParityInterrogator(ModeSMessage reply)
 {
     reply.ParityInterrogatorIdentifier = (int)_BitStream.ReadUInt32(24);
 }
 private void ExtractFlightStatus(ModeSMessage reply)
 {
     reply.FlightStatus = (FlightStatus)_BitStream.ReadByte(3);
 }
 private void ExtractDownlinkRequest(ModeSMessage reply)
 {
     reply.DownlinkRequest = _BitStream.ReadByte(5);
 }
 private void ExtractCapability(ModeSMessage reply)
 {
     reply.Capability = (Capability)_BitStream.ReadByte(3);
 }
 /// <summary>
 /// Decodes the fields from a Comm-D reply (DF = 24).
 /// </summary>
 /// <param name="reply"></param>
 private void DecodeCommD(ModeSMessage reply)
 {
     _BitStream.Skip(1);
     reply.ElmControl = (ElmControl)_BitStream.ReadByte(1);
     reply.DSegmentNumber = _BitStream.ReadByte(4);
     reply.CommDMessage = ReadBytes(10);
     ExtractAircraftParityIdentifier(reply);
 }
 /// <summary>
 /// Decodes the fields from a Comm-B altitude reply (DF = 20).
 /// </summary>
 /// <param name="reply"></param>
 private void DecodeCommBAltitudeReply(ModeSMessage reply)
 {
     ExtractFlightStatus(reply);
     ExtractDownlinkRequest(reply);
     ExtractUtilityMessage(reply);
     ExtractAltitudeCode(reply);
     ExtractCommBMessage(reply);
     ExtractAircraftParityIdentifier(reply);
 }
 /// <summary>
 /// Decodes the fields from an all-call reply (DF = 11).
 /// </summary>
 /// <param name="reply"></param>
 private void DecodeAllCallReply(ModeSMessage reply)
 {
     ExtractCapability(reply);
     ExtractAircraftAddress(reply);
     ExtractParityInterrogator(reply);
 }
        /// <summary>
        /// See interface docs.
        /// </summary>
        /// <param name="modeSMessage"></param>
        /// <returns></returns>
        public AdsbMessage Translate(ModeSMessage modeSMessage)
        {
            AdsbMessage result = null;
            if(modeSMessage != null && modeSMessage.ExtendedSquitterMessage != null && modeSMessage.ExtendedSquitterMessage.Length == 7) {
                _BitStream.Initialise(modeSMessage.ExtendedSquitterMessage);

                result = new AdsbMessage(modeSMessage);
                result.Type = _BitStream.ReadByte(5);

                switch(result.Type) {
                    case 0:     DecodeAirbornePosition(result); break;
                    case 1:
                    case 2:
                    case 3:
                    case 4:     DecodeIdentification(result); break;
                    case 5:
                    case 6:
                    case 7:
                    case 8:     DecodeSurfacePosition(result); break;
                    case 9:
                    case 10:
                    case 11:
                    case 12:
                    case 13:
                    case 14:
                    case 15:
                    case 16:
                    case 17:
                    case 18:    DecodeAirbornePosition(result); break;
                    case 19:    DecodeVelocity(result); break;
                    case 20:
                    case 21:
                    case 22:    DecodeAirbornePosition(result); break;
                    case 28:    DecodeAircraftStatus(result); break;
                    case 29:    DecodeTargetStateAndStatus(result); break;
                    case 31:    DecodeAircraftOperationalStatus(result); break;
                }

                if(_Statistics.Lock != null) {
                    lock(_Statistics.Lock) {
                        ++_Statistics.AdsbCount;
                        ++_Statistics.AdsbMessageFormatCount[(int)result.MessageFormat];
                        ++_Statistics.AdsbTypeCount[result.Type];
                    }
                }
            }

            return result;
        }
 private void ExtractAltitudeCode(ModeSMessage reply)
 {
     reply.Altitude = _BitStream.ReadUInt16(13);
     reply.AltitudeIsMetric = (reply.Altitude & 0x40) != 0;
     if(!reply.AltitudeIsMetric.Value) {
         int? decodedAltitude = ((reply.Altitude & 0x1F80) >> 2) | ((reply.Altitude & 0x20) >> 1) | (reply.Altitude & 0x0f);
         if((reply.Altitude & 0x10) != 0) decodedAltitude = ModeSAltitudeConversion.CalculateBinaryAltitude(decodedAltitude.Value);
         else decodedAltitude = ModeSAltitudeConversion.LookupGillhamAltitude(decodedAltitude.Value);
         reply.Altitude = decodedAltitude;
     }
 }
 /// <summary>
 /// Decodes the fields from an extended squitter reply (DF = 17).
 /// </summary>
 /// <param name="reply"></param>
 private void DecodeExtendedSquitter(ModeSMessage reply)
 {
     ExtractCapability(reply);
     ExtractAircraftAddress(reply);
     ExtractExtendedSquitterMessage(reply);
     ExtractParityInterrogator(reply);
 }
 private void ExtractCommBMessage(ModeSMessage reply)
 {
     reply.CommBMessage = ReadBytes(7);
     if(reply.CommBMessage[0] == 0x20) {
         _BitStream.Skip(-48);
         reply.PossibleCallsign = ModeSCharacterTranslator.ExtractCharacters(_BitStream, 8);
     }
 }
 /// <summary>
 /// Decodes the fields from an extended squitter from non-transponder reply (DF = 18).
 /// </summary>
 /// <param name="reply"></param>
 private void DecodeExtendedSquitterNonTransponder(ModeSMessage reply)
 {
     reply.ControlField = (ControlField)_BitStream.ReadByte(3);
     switch(reply.ControlField) {
         case ControlField.AdsbDeviceTransmittingIcao24:
         case ControlField.AdsbRebroadcastOfExtendedSquitter:
             ExtractAircraftAddress(reply);
             ExtractExtendedSquitterMessage(reply);
             break;
         case ControlField.AdsbDeviceNotTransmittingIcao24:
             reply.NonIcao24Address = (int)_BitStream.ReadUInt32(24);
             ExtractExtendedSquitterMessage(reply);
             break;
         default:
             reply.ExtendedSquitterSupplementaryMessage = ReadBytes(10);
             break;
     }
     ExtractParityInterrogator(reply);
 }
 private void ExtractExtendedSquitterMessage(ModeSMessage reply)
 {
     reply.ExtendedSquitterMessage = ReadBytes(7);
 }
 /// <summary>
 /// Decodes the fields from a long air-to-air surveillance reply (DF = 16).
 /// </summary>
 /// <param name="reply"></param>
 private void DecodeLongAirToAirSurveillance(ModeSMessage reply)
 {
     ExtractVerticalStatus(reply);
     _BitStream.Skip(2);
     ExtractSensitivityLevel(reply);
     _BitStream.Skip(2);
     ExtractReplyInformation(reply);
     _BitStream.Skip(2);
     ExtractAltitudeCode(reply);
     reply.ACASMessage = ReadBytes(7);
     ExtractAircraftParityIdentifier(reply);
 }
 private void ExtractIdentity(ModeSMessage reply)
 {
     var bits = (short)_BitStream.ReadUInt16(13);
     reply.Identity = ModeATranslator.DecodeModeA(bits);
 }
 /// <summary>
 /// Decodes the fields from a military extended squitter reply (DF = 19).
 /// </summary>
 /// <param name="reply"></param>
 private void DecodeMilitaryExtendedSquitter(ModeSMessage reply)
 {
     reply.ApplicationField = (ApplicationField)_BitStream.ReadByte(3);
     if(reply.ApplicationField != ApplicationField.ADSB) {
         reply.ExtendedSquitterSupplementaryMessage = ReadBytes(13);
     } else {
         ExtractAircraftAddress(reply);
         ExtractExtendedSquitterMessage(reply);
         ExtractParityInterrogator(reply);
     }
 }
 private void ExtractReplyInformation(ModeSMessage reply)
 {
     reply.ReplyInformation = _BitStream.ReadByte(4);
 }
 /// <summary>
 /// Decodes the fields from a short air-to-air surveillance reply (DF = 0).
 /// </summary>
 /// <param name="reply"></param>
 private void DecodeShortAirToAirSurveillance(ModeSMessage reply)
 {
     ExtractVerticalStatus(reply);
     reply.CrossLinkCapability = _BitStream.ReadBit();
     _BitStream.Skip(1);
     ExtractSensitivityLevel(reply);
     _BitStream.Skip(2);
     ExtractReplyInformation(reply);
     _BitStream.Skip(2);
     ExtractAltitudeCode(reply);
     ExtractAircraftParityIdentifier(reply);
 }
 private void ExtractUtilityMessage(ModeSMessage reply)
 {
     reply.UtilityMessage = _BitStream.ReadByte(6);
 }
 /// <summary>
 /// Decodes the fields from a surveillance identity reply (DF = 5).
 /// </summary>
 /// <param name="reply"></param>
 private void DecodeSurveillanceIdentityReply(ModeSMessage reply)
 {
     ExtractFlightStatus(reply);
     ExtractDownlinkRequest(reply);
     ExtractUtilityMessage(reply);
     ExtractIdentity(reply);
     ExtractAircraftParityIdentifier(reply);
 }
        /// <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;
        }
 private void ExtractAircraftAddress(ModeSMessage reply)
 {
     reply.Icao24 = (int)_BitStream.ReadUInt32(24);
 }
 /// <summary>
 /// Creates a new object.
 /// </summary>
 /// <param name="utcNow"></param>
 /// <param name="modeSMessage"></param>
 /// <param name="adsbMessage"></param>
 public ModeSMessageEventArgs(DateTime utcNow, ModeSMessage modeSMessage, AdsbMessage adsbMessage)
 {
     ReceivedUtc  = utcNow;
     ModeSMessage = modeSMessage;
     AdsbMessage  = adsbMessage;
 }
 private void ExtractAircraftParityIdentifier(ModeSMessage reply)
 {
     reply.Icao24 = (int)_BitStream.ReadUInt32(24);
 }