Beispiel #1
0
        private string DecodeVelocityOverGroundMsg(ModeSReply msg, DateTime timestamp)
        {
            VelocityOverGroundMsg velocity = (VelocityOverGroundMsg)msg;

            if (msg.ICAO24 == null)
            {
                return("VelocityOverGroundMsg: No ICAO24 found.");
            }
            string icao24 = BitConverter.ToString(msg.ICAO24).Replace("-", String.Empty);
            // check if ICAO is already stored in lookup table
            ADSBInfo info = null;

            if (!adsbinfos.TryGetValue(icao24, out info))
            {
                // no --> add new entry
                info        = new ADSBInfo();
                info.ICAO24 = icao24;
                adsbinfos.Add(icao24, info);
            }
            // add information
            if (velocity.HasValidVelocity)
            {
                info.Speed = velocity.Velocity;
            }
            if (velocity.HasValidHeading)
            {
                info.Heading = velocity.Heading;
            }
            return("[" + info.ICAO24 + "] VelocityOverGroundMsg: Speed=" + info.Speed.ToString() + ", Heading= " + info.Heading.ToString());
        }
Beispiel #2
0
        public string DecodeMessage(string raw_msg, DateTime timestamp)
        {
            // decode an ADS-B message and add information to list
            // cut off first and last character
            raw_msg = raw_msg.Substring(1, raw_msg.Length - 2);
            // do generic decoding first
            ModeSReply msg = LibADSB.Decoder.GenericDecoder(raw_msg);

            if (!msg.CheckParity)
            {
                return("Parity error, no decode.");
            }
            // parity is OK, let's start to sort the messages and calculate
            //                                        Console.WriteLine(msg.ToString());
            // lock adsbinfolist
            lock (adsbinfos)
            {
                try
                {
                    if (msg.GetType() == typeof(IdentificationMsg))
                    {
                        // Identification message;
                        return(DecodeIdentificationMsg(msg, timestamp));
                    }
                    else if (msg.GetType() == typeof(AirbornePositionMsg))
                    {
                        // Airborne position message
                        return(DecodeAirbornePositionMsg(msg, timestamp));
                    }
                    else if (msg.GetType() == typeof(VelocityOverGroundMsg))
                    {
                        // Velocity over ground message
                        return(DecodeVelocityOverGroundMsg(msg, timestamp));
                    }
                    else if (msg.GetType() == typeof(AirspeedHeadingMsg))
                    {
                        // Airspeed heading message
                        return(DecodeAirspeedHeadingMsg(msg, timestamp));
                    }
                }
                catch (Exception ex)
                {
                    string s = msg.GetType().ToString();
                    return("Error while decoding " + s + ": " + ex.Message);
                }
            }
            return("Unknown message.");
        }
Beispiel #3
0
        private string DecodeIdentificationMsg(ModeSReply msg, DateTime timestamp)
        {
            IdentificationMsg ident = (IdentificationMsg)msg;

            if (msg.ICAO24 == null)
            {
                return("IdentifyMsg: No ICAO24 found.");
            }
            string icao24 = BitConverter.ToString(msg.ICAO24).Replace("-", String.Empty);
            // check if ICAO is already stored in lookup table
            ADSBInfo info = null;

            if (!adsbinfos.TryGetValue(icao24, out info))
            {
                // no --> add new entry
                info        = new ADSBInfo();
                info.ICAO24 = icao24;
                adsbinfos.Add(icao24, info);
            }
            // add call sign
            info.Call = ident.getIdentity();
            return("[" + info.ICAO24 + "] IdentificationMsg: Call=" + info.Call);
        }
Beispiel #4
0
        private string DecodeAirbornePositionMsg(ModeSReply msg, DateTime timestamp)
        {
            // Airborne position message --> we need subsequent messages to decode
            AirbornePositionMsg pos = (AirbornePositionMsg)msg;

            if (msg.ICAO24 == null)
            {
                return("AirbornePositionMsg: No ICAO24 found.");
            }
            string icao24 = BitConverter.ToString(msg.ICAO24).Replace("-", String.Empty);
            // check if ICAO is already stored in lookup table
            ADSBInfo info = null;

            if (!adsbinfos.TryGetValue(icao24, out info))
            {
                // no --> add new entry
                info        = new ADSBInfo();
                info.ICAO24 = icao24;
                adsbinfos.Add(icao24, info);
            }
            // adsbinfo found --> update information and calculate position
            // contains valid position?
            if (!pos.HasValidPosition)
            {
                // no --> return error meesage
                return("[" + info.ICAO24 + "] AirbornePositionMsg: No valid position found.");
            }
            info.ICAO24         = icao24;
            info.NICSupplementA = pos.NICSupplementA;
            // position calculated before
            if (!double.IsNaN(info.Lat) & !double.IsNaN(info.Lon))
            {
                try
                {
                    // use local CPR
                    double[] localpos = pos.getLocalPosition(info.Lat, info.Lon);
                    // we have a pos --> store in info and update timestamp
                    info.Lat = localpos[0];
                    info.Lon = localpos[1];
                    if (pos.HasValidAltitude)
                    {
                        info.Alt = pos.Altitude;
                    }
                    info.Timestamp = timestamp;
                    return("[" + info.ICAO24 + "] AirbornePositionMsg: Lat= " + info.Lat.ToString("F8") + ", Lon=" + info.Lon.ToString("F8") + ", Alt= " + info.Alt.ToString() + ", Time= " + info.Timestamp.ToString("HH:mm:ss.fff"));
                }
                catch (Exception ex)
                {
                }
            }
            // no position calculated before
            if (pos.IsOddFormat)
            {
                try
                {
                    // odd message
                    info.LastOddAirborne  = pos;
                    info.LastOddTimestamp = DateTime.UtcNow;
                    // check if even message was received before and not older than 10secs--> calculate global CPR
                    if ((info.LastEvenAirborne != null) && ((info.LastOddTimestamp - info.LastOddTimestamp).TotalSeconds <= 10))
                    {
                        try
                        {
                            double[] globalpos = pos.getGlobalPosition(info.LastEvenAirborne);
                            // we have a position --> store in info and update timestamp
                            info.Lat = globalpos[0];
                            info.Lon = globalpos[1];
                            if (pos.HasValidAltitude)
                            {
                                info.Alt = pos.Altitude;
                            }
                            //                        info.Timestamp = timestamp;
                            return("[" + info.ICAO24 + "] AirbornePositionMsg: Lat= " + info.Lat.ToString("F8") + ", Lon=" + info.Lon.ToString("F8") + ", Alt= " + info.Alt.ToString() + ", Time= " + info.Timestamp.ToString("HH:mm:ss.fff"));
                        }
                        catch
                        {
                            return("[" + info.ICAO24 + "] AirbornePositionMsg: Error while decoding position");
                        }
                    }
                    return("[" + info.ICAO24 + "] AirbornePositionMsg: No decoding possible yet");
                }
                catch (Exception ex)
                {
                }
            }
            // even message
            info.LastEvenAirborne  = pos;
            info.LastEvenTimestamp = DateTime.UtcNow;
            // check if odd message was received before and not older than 10secs --> calculate global CPR
            if ((info.LastOddAirborne != null) && ((info.LastEvenTimestamp - info.LastOddTimestamp).TotalSeconds <= 10))
            {
                try
                {
                    double[] globalpos = pos.getGlobalPosition(info.LastOddAirborne);
                    // we have a position --> store in info and update timestamp
                    info.Lat = globalpos[0];
                    info.Lon = globalpos[1];
                    if (pos.HasValidAltitude)
                    {
                        info.Alt = pos.Altitude;
                    }
//                    info.Timestamp = timestamp;
                    return("[" + info.ICAO24 + "] AirbornePositionMsg: Lat= " + info.Lat.ToString("F8") + ", Lon=" + info.Lon.ToString("F8") + ", Alt= " + info.Alt.ToString() + ", Time= " + info.Timestamp.ToString("HH:mm:ss.fff"));
                }
                catch
                {
                    return("[" + info.ICAO24 + "] AirbornePositionMsg: Error while decoding position");
                }
            }
            else
            {
                return("[" + info.ICAO24 + "] AirbornePositionMsg:No decoding possible yet");
            }
        }
Beispiel #5
0
        /**
         * A top-down ADS-B decoder. Use instanceof to check for the message type.
         * @param raw_message The Mode S message in hex representation
         */
        public static ModeSReply GenericDecoder(String raw_message)
        {
            ModeSReply modes = new ModeSReply(raw_message);

            // check parity; Note: some receivers set parity to 0
            if (modes.IsZeroParity() || modes.CheckParity)
            {
                // check if it is an ADS-B message
                if (modes.DownlinkFormat == 17 || modes.DownlinkFormat == 18)
                {
                    ExtendedSquitter es1090 = new ExtendedSquitter(raw_message);

                    // what kind of extended squitter?
                    byte ftc = es1090.FormatTypeCode;
                    if (ftc >= 1 && ftc <= 4) // identification message
                    {
                        return(new IdentificationMsg(raw_message));
                    }
                    if (ftc >= 5 && ftc <= 8) // surface position message
                    {
                        return(new SurfacePositionMsg(raw_message));
                    }
                    if ((ftc >= 9 && ftc <= 18) || (ftc >= 20 && ftc <= 22)) // airborne position message
                    {
                        return(new AirbornePositionMsg(raw_message));
                    }
                    if (ftc == 19)   // possible velocity message, check subtype
                    {
                        int subtype = es1090.Message[0] & 0x7;

                        if (subtype == 1 || subtype == 2) // velocity over ground
                        {
                            return(new VelocityOverGroundMsg(raw_message));
                        }
                        else if (subtype == 3 || subtype == 4) // airspeed & heading
                        {
                            return(new AirspeedHeadingMsg(raw_message));
                        }
                    }

                    /*
                     * if (ftc == 28) { // aircraft status message, check subtype
                     *  int subtype = es1090.getMessage()[0]&0x7;
                     *
                     *  if (subtype == 1) // emergency/priority status
                     *      return new EmergencyOrPriorityStatusMsg(raw_message);
                     *  if (subtype == 2) // TCAS resolution advisory report
                     *      return new TCASResolutionAdvisoryMsg(raw_message);
                     * }
                     *
                     * if (ftc == 31) { // operational status message
                     *  int subtype = es1090.getMessage()[0]&0x7;
                     *
                     *  if (subtype == 0 || subtype == 1) // airborne or surface?
                     *      return new OperationalStatusMsg(raw_message);
                     * }
                     */
                    return(es1090); // unknown extended squitter
                }
            }
            return(modes); // unknown mode s reply
        }