public void Enqueue(Type type, object data) { BackgroundThreadQueue.Enqueue(new Meta(data, this) { Type = type }); }
/// <summary> /// Called by the listener when a BaseStation message is received. /// </summary> /// <param name="sender"></param> /// <param name="args"></param> private void MessageListener_MessageReceived(object sender, BaseStationMessageEventArgs args) { if (_BackgroundThreadMessageQueue != null) { _BackgroundThreadMessageQueue.Enqueue(args); } }
/// <summary> /// See interface docs. /// </summary> /// <param name="bytes"></param> public void Send(byte[] bytes) { if (_SendQueue != null) { _SendQueue.Enqueue(bytes); } }
/// <summary> /// Called when a listener raises a BaseStation message event. /// </summary> /// <param name="sender"></param> /// <param name="args"></param> private void Listener_Port30003MessageReceived(object sender, BaseStationMessageEventArgs args) { try { var listener = (IListener)sender; _MessageProcessingQueue.Enqueue(new MessageReceived(_Clock.UtcNow, listener, args)); } catch (Exception ex) { OnExceptionCaught(new EventArgs <Exception>(ex)); } }
/// <summary> /// Called every time the provider sends some bytes to us. /// </summary> /// <param name="ar"></param> private void BytesReceived(IAsyncResult ar) { try { var now = Provider.UtcNow; int bytesRead = -1; bool fetchNext = true; try { bytesRead = Provider.EndRead(ar); } catch (ObjectDisposedException) { fetchNext = false; } catch (SocketException) { fetchNext = false; Reconnect(); } if (bytesRead == 0 || _Disposed) { fetchNext = false; if (!_Disposed) { Reconnect(); } } else if (bytesRead > 0) { if (_Statistics.Lock != null) { lock (_Statistics.Lock) _Statistics.BytesReceived += bytesRead; } // This is a bit of a cheat - I don't want the overhead of taking a copy of the read buffer if nothing is // listening to RawBytesReceived, so I take a peek at the event handler before creating the event args... if (RawBytesReceived != null) { var copyRawBytes = new byte[bytesRead]; Array.Copy(Provider.ReadBuffer, 0, copyRawBytes, 0, bytesRead); _MessageProcessingAndDispatchQueue.Enqueue(new MessageDispatch() { RawBytesEventArgs = new EventArgs <byte[]>(copyRawBytes) }); } foreach (var extractedBytes in BytesExtractor.ExtractMessageBytes(Provider.ReadBuffer, 0, bytesRead)) { if (extractedBytes.ChecksumFailed) { ++TotalBadMessages; if (_Statistics.Lock != null) { lock (_Statistics.Lock) ++_Statistics.FailedChecksumMessages; } } else { // Another cheat and for the same reason as explained for the RawBytesReceived message - we don't want to // incur the overhead of copying the extracted bytes if there is nothing listening to the event. if (ModeSBytesReceived != null && extractedBytes.Format == ExtractedBytesFormat.ModeS) { _MessageProcessingAndDispatchQueue.Enqueue(new MessageDispatch() { ModeSBytesEventArgs = new EventArgs <ExtractedBytes>((ExtractedBytes)extractedBytes.Clone()) }); } switch (extractedBytes.Format) { case ExtractedBytesFormat.Port30003: ProcessPort30003MessageBytes(extractedBytes); break; case ExtractedBytesFormat.ModeS: ProcessModeSMessageBytes(now, extractedBytes); break; default: throw new NotImplementedException(); } } } } if (fetchNext) { Provider.BeginRead(BytesReceived); } } catch (Exception ex) { Disconnect(); OnExceptionCaught(new EventArgs <Exception>(ex)); } }
/// <summary> /// Called every time the connection sends some bytes to us. /// </summary> /// <param name="connection"></param> /// <param name="buffer"></param> /// <param name="offset"></param> /// <param name="length"></param> /// <param name="bytesRead"></param> private void BytesReceived(IConnection connection, byte[] buffer, int offset, int length, int bytesRead) { try { var now = _Clock.UtcNow; if (bytesRead > 0) { if (Statistics != null) { Statistics.Lock(r => r.BytesReceived += bytesRead); } _LastMessageUtc = now; // This is a bit of a cheat - I don't want the overhead of taking a copy of the read buffer if nothing is // listening to RawBytesReceived, so I take a peek at the event handler before creating the event args... if (RawBytesReceived != null) { var copyRawBytes = new byte[bytesRead]; Array.Copy(buffer, offset, copyRawBytes, 0, bytesRead); _MessageProcessingAndDispatchQueue.Enqueue(new MessageDispatch() { RawBytesEventArgs = new EventArgs <byte[]>(copyRawBytes) }); } foreach (var extractedBytes in BytesExtractor.ExtractMessageBytes(buffer, offset, bytesRead)) { if (extractedBytes.ChecksumFailed) { ++TotalBadMessages; if (Statistics != null) { Statistics.Lock(r => ++ r.FailedChecksumMessages); } } else { // Another cheat and for the same reason as explained for the RawBytesReceived message - we don't want to // incur the overhead of copying the extracted bytes if there is nothing listening to the event. if (ModeSBytesReceived != null && extractedBytes.Format == ExtractedBytesFormat.ModeS) { _MessageProcessingAndDispatchQueue.Enqueue(new MessageDispatch() { ModeSBytesEventArgs = new EventArgs <ExtractedBytes>((ExtractedBytes)extractedBytes.Clone()) }); } switch (extractedBytes.Format) { case ExtractedBytesFormat.Port30003: ProcessPort30003MessageBytes(extractedBytes); break; case ExtractedBytesFormat.ModeS: ProcessModeSMessageBytes(now, extractedBytes); break; case ExtractedBytesFormat.Compressed: ProcessCompressedMessageBytes(now, extractedBytes); break; case ExtractedBytesFormat.AircraftListJson: ProcessAircraftListJsonMessageBytes(now, extractedBytes); break; case ExtractedBytesFormat.AirnavXRange: ProcessAirnavXRangeMessageBytes(now, extractedBytes); break; default: throw new NotImplementedException(); } } } if (Statistics != null) { Statistics.Lock(r => r.CurrentBufferSize = BytesExtractor.BufferSize); } } Connector.Read(_Buffer, BytesReceived); } catch (Exception ex) { Disconnect(); OnExceptionCaught(new EventArgs <Exception>(ex)); } }
/// <summary> /// Applies the fetched aircraft record to the aircraft detail, raising any events appropriate. /// </summary> /// <param name="detail"></param> /// <param name="databaseAircraft"></param> /// <param name="aircraft"></param> /// <param name="onlineAircraft"></param> /// <param name="isFirstFetch"></param> /// <param name="flightsCount"></param> private AircraftDetail ApplyDatabaseRecord(AircraftDetail detail, BaseStationAircraft databaseAircraft, AircraftOnlineLookupDetail onlineAircraft, IAircraft aircraft, bool isFirstFetch, int flightsCount = -1) { var databaseAircraftChanged = detail == null; if (!databaseAircraftChanged) { if (detail.Aircraft == null) { databaseAircraftChanged = databaseAircraft != null; } else { databaseAircraftChanged = !detail.Aircraft.Equals(databaseAircraft); if (!databaseAircraftChanged && flightsCount > -1 && flightsCount != detail.FlightsCount) { databaseAircraftChanged = true; } } } var onlineAircraftChanged = detail == null; if (!onlineAircraftChanged) { if (detail.OnlineAircraft == null) { onlineAircraftChanged = onlineAircraft != null; } else { onlineAircraftChanged = !detail.OnlineAircraft.ContentEquals(onlineAircraft); } } if (_ForceRefreshOfStandingData && detail != null) { detail.AircraftType = null; } var icaoTypeCode = databaseAircraft == null ? null : databaseAircraft.ICAOTypeCode; if (String.IsNullOrEmpty(icaoTypeCode) && onlineAircraft != null) { icaoTypeCode = onlineAircraft.ModelIcao; } var aircraftType = detail == null ? null : detail.AircraftType; var aircraftTypeChanged = detail == null; if (icaoTypeCode != null && (_ForceRefreshOfStandingData || detail == null || detail.Aircraft == null || detail.ModelIcao != icaoTypeCode)) { aircraftType = _StandingDataManager.FindAircraftType(icaoTypeCode); aircraftTypeChanged = true; } if (databaseAircraftChanged || onlineAircraftChanged || aircraftTypeChanged) { if (flightsCount == -1) { flightsCount = detail != null ? detail.FlightsCount : databaseAircraft == null ? 0 : _AutoConfigDatabase.Database.GetCountOfFlightsForAircraft(databaseAircraft, new SearchBaseStationCriteria() { Date = new FilterRange <DateTime>(DateTime.MinValue, DateTime.MaxValue), }); } detail = new AircraftDetail() { Aircraft = databaseAircraft, OnlineAircraft = onlineAircraft, AircraftType = aircraftType, FlightsCount = flightsCount, Icao24 = aircraft.Icao24, Picture = detail == null ? null : detail.Picture, }; OnFetched(new EventArgs <AircraftDetail>(detail)); } var registration = databaseAircraft != null ? databaseAircraft.Registration : aircraft.Registration; if (registration == null && onlineAircraft != null) { registration = onlineAircraft.Registration; } if (_PictureLookupThread != null) { _PictureLookupThread.Enqueue(new LookupPictureDetail() { Icao = aircraft.Icao24, Registration = registration, PictureDetail = detail == null ? null : detail.Picture, }); } return(detail); }