/// <summary> /// Creates database records and updates internal objects to track an aircraft that is currently transmitting messages. /// </summary> /// <param name="message"></param> private void TrackFlight(BaseStationMessage message) { if (IsTransmissionMessage(message)) { lock (_SyncLock) { if (_Session != null) { var localNow = Provider.LocalNow; FlightRecords flightRecords; if (!_FlightMap.TryGetValue(message.Icao24, out flightRecords)) { flightRecords = new FlightRecords(); _Database.StartTransaction(); try { flightRecords.Aircraft = FetchOrCreateAircraft(localNow, message.Icao24); flightRecords.Flight = CreateFlight(localNow, flightRecords.Aircraft.AircraftID, message.Callsign); flightRecords.EndTimeUtc = Provider.UtcNow; _Database.EndTransaction(); } catch (ThreadAbortException) { } catch (Exception ex) { Debug.WriteLine(String.Format("BaseStationDatabaseWriter.Plugin.TrackFlight caught exception {0}", ex.ToString())); _Database.RollbackTransaction(); throw; } _FlightMap.Add(message.Icao24, flightRecords); } else { if (flightRecords.Flight.Callsign.Length == 0 && !String.IsNullOrEmpty(message.Callsign)) { var databaseVersion = _Database.GetFlightById(flightRecords.Flight.FlightID); flightRecords.Flight.Callsign = databaseVersion.Callsign = message.Callsign; _Database.UpdateFlight(databaseVersion); } } var flight = flightRecords.Flight; flightRecords.EndTimeUtc = Provider.UtcNow; flight.EndTime = localNow; if (message.SquawkHasChanged.GetValueOrDefault()) { flight.HadAlert = true; } if (message.IdentActive.GetValueOrDefault()) { flight.HadSpi = true; } if (message.Squawk == 7500 || message.Squawk == 7600 || message.Squawk == 7700) { flight.HadEmergency = true; } UpdateFirstLastValues(message, flight, flightRecords); UpdateMessageCounters(message, flight); } } } }
/// <summary> /// Creates or reads all of the database records associated with a <see cref="FlightRecords"/> object. /// </summary> /// <param name="flightRecords"></param> private void WriteFlightRecords(FlightRecords flightRecords) { if (flightRecords.Aircraft.AircraftID == 0 && flightRecords.Flight.FlightID == 0) { _Database.PerformInTransaction(() => { var aircraft = FetchOrCreateAircraft(flightRecords.Aircraft.FirstCreated, flightRecords.Aircraft.ModeS); if (aircraft != null) { var flight = CreateFlight(flightRecords.Flight.StartTime, aircraft.AircraftID, flightRecords.Flight.Callsign); lock (_SyncLock) { flightRecords.Aircraft = aircraft; flightRecords.Flight = ApplyFlightDetails(flightRecords.Flight, flight); } } return(true); }); } }
/// <summary> /// Creates or reads all of the database records associated with a <see cref="FlightRecords"/> object. /// </summary> /// <param name="flightRecords"></param> private void WriteFlightRecords(FlightRecords flightRecords) { if (flightRecords.Aircraft.AircraftID == 0 && flightRecords.Flight.FlightID == 0) { _Database.StartTransaction(); try { var aircraft = FetchOrCreateAircraft(flightRecords.Aircraft.FirstCreated, flightRecords.Aircraft.ModeS); if (aircraft != null) { var flight = CreateFlight(flightRecords.Flight.StartTime, aircraft.AircraftID, flightRecords.Flight.Callsign); _Database.EndTransaction(); lock (_SyncLock) { flightRecords.Aircraft = aircraft; flightRecords.Flight = ApplyFlightDetails(flightRecords.Flight, flight); } } } catch { _Database.RollbackTransaction(); throw; } } }
/// <summary> /// Updates the FirstX / LastX pairs of values of an in-store flight record. /// </summary> /// <param name="message"></param> /// <param name="flight"></param> /// <param name="flightRecords"></param> /// <param name="isMlat"></param> private static void UpdateFirstLastValues(BaseStationMessage message, BaseStationFlight flight, FlightRecords flightRecords, bool isMlat) { bool isLocationZeroZero = message.Latitude.GetValueOrDefault() == 0F && message.Longitude.GetValueOrDefault() == 0F; if (message.Latitude != null && !isLocationZeroZero) { if (flight.FirstLat == null) { flight.FirstLat = message.Latitude; } flight.LastLat = message.Latitude; } if (message.Longitude != null && !isLocationZeroZero) { if (flight.FirstLon == null) { flight.FirstLon = message.Longitude; } flight.LastLon = message.Longitude; } if (message.Track != null) { if (flight.FirstTrack == null) { flight.FirstTrack = message.Track; } flight.LastTrack = message.Track; } if (!isMlat) { if (message.Altitude != null) { if (flight.FirstAltitude == null) { flight.FirstAltitude = message.Altitude; } flight.LastAltitude = message.Altitude; } if (message.GroundSpeed != null) { if (flight.FirstGroundSpeed == null) { flight.FirstGroundSpeed = message.GroundSpeed; } flight.LastGroundSpeed = message.GroundSpeed; } if (message.OnGround != null) { if (flightRecords.OnGround == null) { flightRecords.OnGround = flight.FirstIsOnGround = message.OnGround.Value; } flight.LastIsOnGround = message.OnGround.Value; } if (message.Squawk != null) { if (flight.FirstSquawk == null) { flight.FirstSquawk = message.Squawk; } flight.LastSquawk = message.Squawk; } if (message.VerticalRate != null) { if (flight.FirstVerticalRate == null) { flight.FirstVerticalRate = message.VerticalRate; } flight.LastVerticalRate = message.VerticalRate; } } }
/// <summary> /// Creates database records and updates internal objects to track an aircraft that is currently transmitting messages. /// </summary> /// <param name="message"></param> /// <param name="isMlat"></param> /// <remarks> /// This defers the recording of the flight for as long as possible so that if the database is locked then we don't /// have a record of the flight, and the next message will try again to record the flight. /// </remarks> private void TrackFlight(BaseStationMessage message, bool isMlat) { if (IsTransmissionMessage(message)) { lock (_SyncLock) { if (_Session != null) { var localNow = Provider.LocalNow; var icao24 = CustomConvert.Icao24(message.Icao24); if (icao24 > 0) { FlightRecords flightRecords; if (!_FlightMap.TryGetValue(icao24, out flightRecords)) { flightRecords = new FlightRecords() { Aircraft = new BaseStationAircraft() { ModeS = message.Icao24, FirstCreated = localNow, }, Flight = new BaseStationFlight() { Callsign = message.Callsign, StartTime = localNow, NumADSBMsgRec = 0, NumAirCallRepMsgRec = 0, NumAirPosMsgRec = 0, NumAirToAirMsgRec = 0, NumAirVelMsgRec = 0, NumIDMsgRec = 0, NumModeSMsgRec = 0, NumPosMsgRec = 0, NumSurAltMsgRec = 0, NumSurIDMsgRec = 0, NumSurPosMsgRec = 0, }, }; _FlightMap.Add(icao24, flightRecords); } var flight = flightRecords.Flight; flightRecords.EndTimeUtc = Provider.UtcNow; flight.EndTime = localNow; if (!isMlat) { if (message.SquawkHasChanged.GetValueOrDefault()) { flight.HadAlert = true; } if (message.IdentActive.GetValueOrDefault()) { flight.HadSpi = true; } if (message.Squawk == 7500 || message.Squawk == 7600 || message.Squawk == 7700) { flight.HadEmergency = true; } } UpdateFirstLastValues(message, flight, flightRecords, isMlat); UpdateMessageCounters(message, flight); if (!String.IsNullOrEmpty(message.Callsign)) { if (message.Callsign != flightRecords.Flight.Callsign) { flightRecords.Flight.Callsign = message.Callsign; } } } } } } }
/// <summary> /// Creates database records and updates internal objects to track an aircraft that is currently transmitting messages. /// </summary> /// <param name="message"></param> private void TrackFlight(BaseStationMessage message) { if(IsTransmissionMessage(message)) { lock(_SyncLock) { if(_Session != null) { var localNow = Provider.LocalNow; FlightRecords flightRecords; if(!_FlightMap.TryGetValue(message.Icao24, out flightRecords)) { flightRecords = new FlightRecords(); _Database.StartTransaction(); try { flightRecords.Aircraft = FetchOrCreateAircraft(localNow, message.Icao24); flightRecords.Flight = CreateFlight(localNow, flightRecords.Aircraft.AircraftID, message.Callsign); flightRecords.EndTimeUtc = Provider.UtcNow; _Database.EndTransaction(); } catch(ThreadAbortException) { } catch(Exception ex) { Debug.WriteLine(String.Format("BaseStationDatabaseWriter.Plugin.TrackFlight caught exception {0}", ex.ToString())); _Database.RollbackTransaction(); throw; } _FlightMap.Add(message.Icao24, flightRecords); } else { if(flightRecords.Flight.Callsign.Length == 0 && !String.IsNullOrEmpty(message.Callsign)) { var databaseVersion = _Database.GetFlightById(flightRecords.Flight.FlightID); flightRecords.Flight.Callsign = databaseVersion.Callsign = message.Callsign; _Database.UpdateFlight(databaseVersion); } } var flight = flightRecords.Flight; flightRecords.EndTimeUtc = Provider.UtcNow; flight.EndTime = localNow; if(message.SquawkHasChanged.GetValueOrDefault()) flight.HadAlert = true; if(message.IdentActive.GetValueOrDefault()) flight.HadSpi = true; if(message.Squawk == 7500 || message.Squawk == 7600 || message.Squawk == 7700) flight.HadEmergency = true; UpdateFirstLastValues(message, flight, flightRecords); UpdateMessageCounters(message, flight); } } } }
/// <summary> /// Updates the FirstX / LastX pairs of values of an in-store flight record. /// </summary> /// <param name="message"></param> /// <param name="flight"></param> /// <param name="flightRecords"></param> private static void UpdateFirstLastValues(BaseStationMessage message, BaseStationFlight flight, FlightRecords flightRecords) { bool isLocationZeroZero = message.Latitude.GetValueOrDefault() == 0F && message.Longitude.GetValueOrDefault() == 0F; if(message.Altitude != null) { if(flight.FirstAltitude == null) flight.FirstAltitude = message.Altitude; flight.LastAltitude = message.Altitude; } if(message.GroundSpeed != null) { if(flight.FirstGroundSpeed == null) flight.FirstGroundSpeed = message.GroundSpeed; flight.LastGroundSpeed = message.GroundSpeed; } if(message.OnGround != null) { if(flightRecords.OnGround == null) flightRecords.OnGround = flight.FirstIsOnGround = message.OnGround.Value; flight.LastIsOnGround = message.OnGround.Value; } if(message.Latitude != null && !isLocationZeroZero) { if(flight.FirstLat == null) flight.FirstLat = message.Latitude; flight.LastLat = message.Latitude; } if(message.Longitude != null && !isLocationZeroZero) { if(flight.FirstLon == null) flight.FirstLon = message.Longitude; flight.LastLon = message.Longitude; } if(message.Squawk != null) { if(flight.FirstSquawk == null) flight.FirstSquawk = message.Squawk; flight.LastSquawk = message.Squawk; } if(message.Track != null) { if(flight.FirstTrack == null) flight.FirstTrack = message.Track; flight.LastTrack = message.Track; } if(message.VerticalRate != null) { if(flight.FirstVerticalRate == null) flight.FirstVerticalRate = message.VerticalRate; flight.LastVerticalRate = message.VerticalRate; } }