Beispiel #1
0
        public static string GetCot(LocationObject location)
        {
            var lastTime = DateTime.Parse(location.Lasttime);
            var timeString = lastTime.ToString("yyyy-MM-ddTHH:mm:ssZ");

            // Do we want to add anything to the callsign for the ID?
            //"<?xml version=\"1.0\" standalone=\"yes\"?><event version=\"2.0\" uid=\"{0}\" type=\"a-f-A\" how=\"m-r\" time=\"{1}\" start=\"{1}\" stale=\"{2}\"><point lat=\"{3}\" lon=\"{4}\" ce=20\" le=\"20\" hae=\"{5}\" /></event>\"";
            return string.Format(_cotTemplate, location.Srccall, timeString, GetStaleTime(), location.Lat, location.Lng, location.Hae);
        }
Beispiel #2
0
        private static LocationObject ParseBody(string source, string body)
        {
            LocationObject loc = new LocationObject();
            loc.Srccall = source;
            if (source == "IW7DGY")
            {

            }
            var bodyChars = body.ToCharArray();
            var packetType = bodyChars[0];

            if (packetType == '=' || packetType =='/' ||  packetType =='@'  )
            {
                // regular position packet

                if (body.Length < 10)
                {
                    loc.Error = "Packet is less than 10 characters. Too short.";
                }

                // Normal or compressed location packet, with or without
                // timestamp, with or without messaging capability
                // ! and / have messaging, / and @ have a prepended
                // timestamp

                var cursor = 1;

                if (packetType == '/' || packetType == '@')
                {
                    //Process timestamp.
                    loc.Lasttime = ParseTime(body);
                    cursor += 7;
                }
                char posChar = (char) bodyChars[cursor];

                if ('0' <= posChar && posChar <= '9')
                {
                    // Latitude:
                    /*Latitude is expressed as a fixed 8-character field, in degrees and decimal
                    minutes (to two decimal places), followed by the letter N for north or S for
                    south.
                     Latitude degrees are in the range 00 to 90. Latitude minutes are expressed as
                    whole minutes and hundredths of a minute, separated by a decimal point.
                     For example:
                     4903.50N is 49 degrees 3 minutes 30 seconds north.
                     In generic format examples, the latitude is shown as the 8-character string
                    ddmm.hhN (i.e. degrees, minutes and hundredths of a minute north).*/

                    var rawLat = body.Substring(cursor, 8);
                    loc.Lat = rawLat.Insert(2, " ");

                    //Longitude
                    /*Longitude is expressed as a fixed 9-character field, in degrees and decimal
                    minutes (to two decimal places), followed by the letter E for east or W for
                    west.
                     Longitude degrees are in the range 000 to 180. Longitude minutes are
                    expressed as whole minutes and hundredths of a minute, separated by a
                    decimal point.
                     For example:
                     07201.75W is 72 degrees 1 minute 45 seconds west.
                     In generic format examples, the longitude is shown as the 9-character string
                    dddmm.hhW (i.e. degrees, minutes and hundredths of a minute west).
                     */
                    var rawLng = body.Substring(cursor + 9, 9);
                    loc.Lng = rawLng.Insert(3, " ");
                }
                else // compressed packet
                {
                             //	if (validSymTableCompressed(posChar)) { /* [\/\\A-Za-j] */
                            // compressed position packet
                    //		position = PositionParser.parseCompressed(msgBody, cursor);
                    //		this.extension = PositionParser.parseCompressedExtension(msgBody, cursor);
                    ////		positionSource = "Compressed";
                    loc.Error = "Compressed packet. I don't know how to handle that yet.";
                }
            }
            else if(packetType == '`' || packetType == '\\')
            {
                // MIC-e packet
                loc.Error = "MIC-e packet. I don't know how to handle that yet.";
            }
            else if (packetType == '!')
            {
                //Ultimeter 2000 weather
                // instrument packet
                loc.Error = "Ultimeter 2000 packet. I don't think I want to know how to handle that packet type.";
            }
            else if (packetType == '$')
            {
                // NMEA packet

                loc.Error = "NMEA packet. I don't know how to handle that yet.";
            }
            else
            {
                // Not a position message

                loc.Error = "Packet does not appear to be a position message.";
            }

            return loc;
        }
Beispiel #3
0
        // Monitors log file generated by APRSIS32 APRS radio software
        void _fileSystemWatcher_Changed(object sender, FileSystemEventArgs e)
        {
            try
            {
                if (e.Name == "APRSIS32.log")
                {
                    var lines = File.ReadAllLines(e.FullPath);

                        int counter = 0;
                        string line = "";
                        string uid = "";
                        string time = "";
                        string lat = "";
                        string lng = "";
                        string hae = "";
                        string callsign = "";
                        string comment = "";

                            if (line.Contains(textBoxCallsign.Text))
                            {
                                var elements = line.Split('/');

                                // If there are 8 elements, we hope this is an IGated position message...
                                if (elements.Length == 8)
                                {
                                    // This is what is in my sample file...
                                    /*
                                        [0]	"IGate:WinMain:2014-05-10T20:22:03.526 RFtoIS:[Mobilinkd]IGated KG6PPZ-11>KG6PPZ,WIDE2-1,qAR,KG6PPZ:"
                                        [1]	"202201h3635.49N"
                                        [2]	"08716.31WO000"
                                        [3]	"000"
                                        [4]	"A=000553"
                                        [5]	"Ti=32"
                                        [6]	"Te=70"
                                        [7]	"V=11429 ForceX high altitude balloon test"

                                     */

                                    //TODO: figure out how to get timestamp from additional msgs we might process.

                                    // This works for  IGATE  and KISS log entries
                                    var dateIndex = elements[0].IndexOf(DateTime.Now.Year.ToString());
                                    if (dateIndex >= 0)
                                    {
                                            // TODO: if we are going to process the line, log it
                                            UpdateOutput("Processing log file line: " + line);

                                            //Get callsign -  need entire callsign because chase car and balloon use same one
                                            // with different extension
                                            var callsignIndex = elements[0].IndexOf(textBoxCallsign.Text);
                                            if (callsignIndex >= 0)
                                            {
                                                var endCallsignIndex = elements[0].IndexOf('>');
                                                callsign = elements[0].Substring(callsignIndex, endCallsignIndex - callsignIndex);
                                            }

                                            var index = elements[1].IndexOf('h');
                                            if (index > 0)
                                            {
                                                var rawTime = elements[1].Substring(0, index);
                                                var rawLat = elements[1].Substring(index + 1);

                                                // Get raw lat into a decimal string
                                                var degrees = int.Parse(rawLat.Substring(0, 2));
                                                var decimalMinutes = decimal.Parse(rawLat.Substring(2, rawLat.Length - 3));

                                                // limit to 5 decimal places
                                                var decimalDegrees = degrees + (decimalMinutes / 60);

                                                lat = decimalDegrees.ToString("F5", System.Globalization.CultureInfo.InvariantCulture);

                                                if (rawTime.Length == 6)
                                                {
                                                    var hour = int.Parse(rawTime.Substring(0, 2));
                                                    var minute = int.Parse(rawTime.Substring(2, 2));
                                                    var second = int.Parse(rawTime.Substring(4, 2));
                                                    DateTime msgTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, hour, minute, second);

                                                    time = msgTime.ToString("yyyy-MM-ddTHH:mm:ssZ");
                                                }
                                            }

                                            // Assuming western hemisphere...
                                            index = elements[2].IndexOf('W');
                                            if (index > 0)
                                            {
                                                var rawLon = elements[2].Substring(0, index);
                                                var degrees = int.Parse(rawLon.Substring(0, 3));
                                                var decimalMinutes = decimal.Parse(rawLon.Substring(3));
                                                var decimalDegrees = degrees + (decimalMinutes / 60);

                                                //limit to 5 decimal places
                                                lng = decimalDegrees.ToString("F5", System.Globalization.CultureInfo.InvariantCulture);
                                            }

                                            // parse altitude
                                            if (!string.IsNullOrEmpty(elements[4]))
                                            {
                                                hae = elements[4].Substring(elements[4].IndexOf("A=") + 2);
                                            }

                                            //TODO: looks like there is another field before the comment... what is it?
                                            comment = elements[7];

                                            // Srccall, Lat, Lng, Hae, Lasttime, Comment);
                                            var location = new LocationObject
                                            {
                                                Srccall = callsign,
                                                Lat = lat,
                                                Lng = lng,
                                                Hae = hae,
                                                Lasttime = time,
                                                Comment = comment
                                            };

                                            EmitCot(location);
                                        }
                                    }
                                }
                            }

            }
            finally
            {
            }
        }
Beispiel #4
0
        // Parses a line from the log file generated by APRSIS32 APRS radio software
        void ProcessLine(string line)
        {
            if (!line.Contains(textBoxCallsign.Text))
                return;
            try
            {
                int counter = 0;
                string uid = "";
                string time = "";
                string lat = "";
                string lng = "";
                string hae = "";
                string callsign = "";
                string comment = "";

                var elements = line.Split('/');
                if (elements.Length == 2)
                {
                    /*
                            [0]	"MyCall:WinMain:2014-05-31T19:03:00.367 [TransmitAPRS] KG6PPZ>APWW10,WIDE1-1,WIDE2-1:@190300h3635.50N"
                            [1]	"08716.35WkAPRS-IS for Win32"
                     */

                    var dateIndex = elements[0].IndexOf(DateTime.Now.Year.ToString());
                    if (dateIndex >= 0)
                    {
                        var spaceIndex = elements[0].IndexOf(' ');
                        var thisTime = elements[0].Substring(dateIndex, elements[0].IndexOf(' ') - dateIndex);

                        //if we are going to process the line, log it
                        UpdateOutput("Processing log file line: " + line);

                        //Get callsign -  need entire callsign because chase car and balloon use same one
                        // with different extension
                        var callsignIndex = elements[0].IndexOf(textBoxCallsign.Text);
                        if (callsignIndex >= 0)
                        {
                            var endCallsignIndex = elements[0].IndexOf('>');
                            callsign = elements[0].Substring(callsignIndex, endCallsignIndex - callsignIndex);
                        }

                        // messages that parse into 4 elements have the time before the first '/'
                        var index = elements[0].IndexOf('@');

                        if (index > 0)
                        {
                            var timeLatPart = elements[0].Substring(index);
                            var timeSeparatorIndex = timeLatPart.IndexOf('h');

                            if (timeSeparatorIndex > 0)
                            {
                                var rawTime = timeLatPart.Substring(1, timeSeparatorIndex - 1);
                                var rawLat = timeLatPart.Substring(timeSeparatorIndex + 1);

                                // Get raw lat into a decimal string
                                var degrees = int.Parse(rawLat.Substring(0, 2));
                                var decimalMinutes = decimal.Parse(rawLat.Substring(2, rawLat.Length - 3));

                                // limit to 5 decimal places
                                var decimalDegrees = degrees + (decimalMinutes / 60);

                                lat = decimalDegrees.ToString("F5", System.Globalization.CultureInfo.InvariantCulture);

                                if (rawTime.Length == 6)
                                {
                                    var hour = int.Parse(rawTime.Substring(0, 2));
                                    var minute = int.Parse(rawTime.Substring(2, 2));
                                    var second = int.Parse(rawTime.Substring(4, 2));
                                    DateTime msgTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, hour, minute, second);

                                    time = msgTime.ToString("yyyy-MM-ddTHH:mm:ssZ");
                                }
                            }
                        }

                        // Assuming western hemisphere...
                        index = elements[1].IndexOf('W');
                        if (index > 0)
                        {
                            var rawLon = elements[1].Substring(0, index);

                            var degrees = int.Parse(rawLon.Substring(0, 3));
                            var decimalMinutes = decimal.Parse(rawLon.Substring(3));
                            var decimalDegrees = degrees + (decimalMinutes / 60);
                            // make longitude negative for western hemisphere
                            decimalDegrees = decimalDegrees - (2 * decimalDegrees);

                            //limit to 5 decimal places
                            lng = decimalDegrees.ToString("F5", System.Globalization.CultureInfo.InvariantCulture);

                            // parse comment (this size message doesn't have altitude.
                            if (elements[1].Length > index)
                            {
                                comment = elements[1].Substring(index + 1);
                            }
                        }

                        // Srccall, Lat, Lng, Hae, Lasttime, Comment);
                        var location = new LocationObject
                        {
                            Srccall = callsign,
                            Lat = lat,
                            Lng = lng,
                            Hae = hae,
                            Lasttime = time,
                            Comment = comment
                        };

                        EmitCot(location);
                    }

                }
                else if (elements.Length == 4)
                {
                    // Sample of own location from file
                    /*
                        [0]	"MyCall:WinMain:2014-06-14T15:29:55.108 [TransmitAPRS] KG6PPZ>APWW10,WIDE1-1,WIDE2-1:@152953h3635.52N"
                        [1]	"08716.29Wk056"
                        [2]	"000"
                        [3]	"A=000708APRS-IS for Win32"

                        */
                    var dateIndex = elements[0].IndexOf(DateTime.Now.Year.ToString());
                    if (dateIndex >= 0)
                    {
                        var spaceIndex = elements[0].IndexOf(' ');
                        var thisTime = elements[0].Substring(dateIndex, elements[0].IndexOf(' ') - dateIndex);

                        //if we are going to process the line, log it
                        UpdateOutput("Processing log file line: " + line);

                        //Get callsign -  need entire callsign because chase car and balloon use same one
                        // with different extension
                        var callsignIndex = elements[0].IndexOf(textBoxCallsign.Text);
                        if (callsignIndex >= 0)
                        {
                            var endCallsignIndex = elements[0].IndexOf('>');
                            callsign = elements[0].Substring(callsignIndex, endCallsignIndex - callsignIndex);
                        }

                        // messages that parse into 4 elements have the time before the first '/'
                        var index = elements[0].IndexOf('@');

                        if (index > 0)
                        {
                            var timeLatPart = elements[0].Substring(index);
                            var timeSeparatorIndex = timeLatPart.IndexOf('h');

                            if (timeSeparatorIndex > 0)
                            {
                                var rawTime = timeLatPart.Substring(1, timeSeparatorIndex - 1);
                                var rawLat = timeLatPart.Substring(timeSeparatorIndex + 1);

                                // Get raw lat into a decimal string
                                var degrees = int.Parse(rawLat.Substring(0, 2));
                                var decimalMinutes = decimal.Parse(rawLat.Substring(2, rawLat.Length - 3));

                                // limit to 5 decimal places
                                var decimalDegrees = degrees + (decimalMinutes / 60);

                                lat = decimalDegrees.ToString("F5", System.Globalization.CultureInfo.InvariantCulture);

                                if (rawTime.Length == 6)
                                {
                                    var hour = int.Parse(rawTime.Substring(0, 2));
                                    var minute = int.Parse(rawTime.Substring(2, 2));
                                    var second = int.Parse(rawTime.Substring(4, 2));
                                    DateTime msgTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, hour, minute, second);

                                    time = msgTime.ToString("yyyy-MM-ddTHH:mm:ssZ");
                                }
                            }
                        }

                        // Assuming western hemisphere...
                        index = elements[1].IndexOf('W');
                        if (index > 0)
                        {
                            var rawLon = elements[1].Substring(0, index);
                            var degrees = int.Parse(rawLon.Substring(0, 3));
                            var decimalMinutes = decimal.Parse(rawLon.Substring(3));
                            var decimalDegrees = degrees + (decimalMinutes / 60);
                            // make longitude negative for western hemisphere
                            decimalDegrees = decimalDegrees - (2 * decimalDegrees);

                            //limit to 5 decimal places
                            lng = decimalDegrees.ToString("F5", System.Globalization.CultureInfo.InvariantCulture);

                        }

                        // parse altitude and comment
                        if (!string.IsNullOrEmpty(elements[3]))
                        {
                            hae = elements[3].Substring(elements[3].IndexOf("A=") + 2, 6);
                            comment = elements[3].Substring(8);
                        }

                        // Srccall, Lat, Lng, Hae, Lasttime, Comment);
                        var location = new LocationObject
                        {
                            Srccall = callsign,
                            Lat = lat,
                            Lng = lng,
                            Hae = hae,
                            Lasttime = time,
                            Comment = comment
                        };

                        EmitCot(location);
                    }
                }

                     // If there are 8 elements, we hope this is an expected position message...
                else if (elements.Length == 8)
                {
                    // sample  of IGate data from file...
                    /*
                        [0]	"IGate:WinMain:2014-05-10T20:22:03.526 RFtoIS:[Mobilinkd]IGated KG6PPZ-11>KG6PPZ,WIDE2-1,qAR,KG6PPZ:"
                        [1]	"202201h3635.49N"
                        [2]	"08716.31WO000"
                        [3]	"000"
                        [4]	"A=000553"
                        [5]	"Ti=32"
                        [6]	"Te=70"
                        [7]	"V=11429 ForceX high altitude balloon test"

                     */

                    var dateIndex = elements[0].IndexOf(DateTime.Now.Year.ToString());
                    if (dateIndex >= 0)
                    {
                        var spaceIndex = elements[0].IndexOf(' ');
                        var thisTime = elements[0].Substring(dateIndex, elements[0].IndexOf(' ') - dateIndex);

                        // TODO: if we are going to process the line, log it
                        UpdateOutput("Processing log file line: " + line);

                        //Get callsign -  need entire callsign because chase car and balloon use same one
                        // with different extension
                        var callsignIndex = elements[0].IndexOf(textBoxCallsign.Text);
                        if (callsignIndex >= 0)
                        {
                            var endCallsignIndex = elements[0].IndexOf('>');
                            callsign = elements[0].Substring(callsignIndex, endCallsignIndex - callsignIndex);
                        }

                        var index = elements[1].IndexOf('h');
                        if (index > 0)
                        {
                            var rawTime = elements[1].Substring(0, index);
                            var rawLat = elements[1].Substring(index + 1);

                            // Get raw lat into a decimal string
                            var degrees = int.Parse(rawLat.Substring(0, 2));
                            var decimalMinutes = decimal.Parse(rawLat.Substring(2, rawLat.Length - 3));

                            // limit to 5 decimal places
                            var decimalDegrees = degrees + (decimalMinutes / 60);

                            lat = decimalDegrees.ToString("F5", System.Globalization.CultureInfo.InvariantCulture);

                            if (rawTime.Length == 6)
                            {
                                var hour = int.Parse(rawTime.Substring(0, 2));
                                var minute = int.Parse(rawTime.Substring(2, 2));
                                var second = int.Parse(rawTime.Substring(4, 2));
                                DateTime msgTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, hour, minute, second);

                                time = msgTime.ToString("yyyy-MM-ddTHH:mm:ssZ");
                            }
                        }

                        // Assuming western hemisphere...
                        index = elements[2].IndexOf('W');
                        if (index > 0)
                        {
                            var rawLon = elements[2].Substring(0, index);
                            var degrees = int.Parse(rawLon.Substring(0, 3));
                            var decimalMinutes = decimal.Parse(rawLon.Substring(3));
                            var decimalDegrees = degrees + (decimalMinutes / 60);
                            // Need negative longitude for W hemisphere
                            decimalDegrees = decimalDegrees - (2 * decimalDegrees);

                            //limit to 5 decimal places
                            lng = decimalDegrees.ToString("F5", System.Globalization.CultureInfo.InvariantCulture);
                        }

                        // parse altitude
                        if (!string.IsNullOrEmpty(elements[4]))
                        {
                            hae = elements[4].Substring(elements[4].IndexOf("A=") + 2);
                        }

                        //TODO: looks like there is another field before the comment... what is it?
                        comment = elements[7];

                        // Srccall, Lat, Lng, Hae, Lasttime, Comment);
                        var location = new LocationObject
                        {
                            Srccall = callsign,
                            Lat = lat,
                            Lng = lng,
                            Hae = hae,
                            Lasttime = time,
                            Comment = comment
                        };

                        EmitCot(location);

                    }
                }

            }
            catch (Exception ex)
            {
            }
            finally
            {
            }
        }
Beispiel #5
0
 private void EmitCot(LocationObject location)
 {
     if(_udpClient == null)
     {
         InitializeUdp();
     }
     if (_udpClient != null)
     {
         string cotString = CotGenerator.GetCot(location);
         _udpClient.SendUdp(cotString);
     }
 }