From 6d96912ace25732861178720fc1b56e8c17f3812 Mon Sep 17 00:00:00 2001 From: pschuler78 Date: Fri, 8 Oct 2021 20:34:37 +0200 Subject: [PATCH 1/3] Updated projects to use .net core 3.1 instead unsupported EOL 2.0 version --- AprsClientExample/AprsClientExample.csproj | 4 ++-- Skyhop.Aprs.Client.Tests/Skyhop.Aprs.Client.Tests.csproj | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/AprsClientExample/AprsClientExample.csproj b/AprsClientExample/AprsClientExample.csproj index ba22fb6..691fcd2 100644 --- a/AprsClientExample/AprsClientExample.csproj +++ b/AprsClientExample/AprsClientExample.csproj @@ -1,8 +1,8 @@ - + Exe - netcoreapp2.0 + netcoreapp3.1 diff --git a/Skyhop.Aprs.Client.Tests/Skyhop.Aprs.Client.Tests.csproj b/Skyhop.Aprs.Client.Tests/Skyhop.Aprs.Client.Tests.csproj index c60b54d..e0c5326 100644 --- a/Skyhop.Aprs.Client.Tests/Skyhop.Aprs.Client.Tests.csproj +++ b/Skyhop.Aprs.Client.Tests/Skyhop.Aprs.Client.Tests.csproj @@ -1,7 +1,7 @@ - + - netcoreapp2.0 + netcoreapp3.1 false From 42e40f223d8eab9130b39de78fda6ceea53b1b6a Mon Sep 17 00:00:00 2001 From: pschuler78 Date: Sat, 9 Oct 2021 17:39:29 +0200 Subject: [PATCH 2/3] Added AddressType, AircraftType, StealthMode and NotrackingFlag properties to AprsMessage --- Skyhop.Aprs.Client.Tests/AprsMessageTests.cs | 76 ++++++++++++++++++++ Skyhop.Aprs.Client/Enums/AddressType.cs | 14 ++++ Skyhop.Aprs.Client/Enums/AircraftType.cs | 26 +++++++ Skyhop.Aprs.Client/Models/AprsMessage.cs | 13 ++++ Skyhop.Aprs.Client/Models/PacketInfo.cs | 27 +++++++ 5 files changed, 156 insertions(+) create mode 100644 Skyhop.Aprs.Client/Enums/AddressType.cs create mode 100644 Skyhop.Aprs.Client/Enums/AircraftType.cs diff --git a/Skyhop.Aprs.Client.Tests/AprsMessageTests.cs b/Skyhop.Aprs.Client.Tests/AprsMessageTests.cs index bf4d13c..0bab78f 100644 --- a/Skyhop.Aprs.Client.Tests/AprsMessageTests.cs +++ b/Skyhop.Aprs.Client.Tests/AprsMessageTests.cs @@ -1,6 +1,7 @@ using System; using Boerman.Core.Spatial; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Skyhop.Aprs.Client.Enums; using Skyhop.Aprs.Client.Models; namespace Boerman.Aprs.Client.Tests @@ -30,6 +31,81 @@ public void TestFanetMessageParsing() Assert.IsTrue(result.StationRoute[2] == "Letzi"); Assert.IsTrue(result.Symbol == Skyhop.Aprs.Client.Enums.Symbol.Glider); Assert.IsTrue(result.TurnRate == 0); + Assert.AreEqual(AircraftType.Paraglider, result.AircraftType); + } + + [TestMethod] + public void TestOGNGliderHB1669LszxMessageParsing() + { + var message = "ICA4B4B2C>APRS,qAS,LSZX:/090803h4710.41N/00902.63E'152/051/A=002129 !W18! id054B4B2C -138fpm -1.6rot 24.0dB 0e -1.8kHz gps2x2"; + + var result = PacketInfo.Parse(message); + + Assert.IsTrue(result != null); + Assert.IsTrue(result.Altitude.FeetAboveSeaLevel == 2129); + Assert.IsTrue(result.Callsign == "ICA4B4B2C"); + Assert.IsTrue(result.ClimbRate == -138); + Assert.IsTrue(result.DataType == Skyhop.Aprs.Client.Enums.DataType.PositionWithTimestampNoAprsMessaging); + Assert.IsTrue(result.Direction.Degrees == 152); + Assert.IsTrue(result.Latitude.AbsoluteValue == 47.1735); + Assert.IsTrue(result.Longitude.AbsoluteValue == 9.0438333333333336); + Assert.IsTrue(result.MicEMessageType == Skyhop.Aprs.Client.Enums.MicEMessageType.OffDuty); + Assert.IsTrue(result.Speed.Knots == 51); + Assert.IsTrue(result.StationRoute[0] == "APRS"); + Assert.IsTrue(result.StationRoute[1] == "qAS"); + Assert.IsTrue(result.StationRoute[2] == "LSZX"); + Assert.IsTrue(result.Symbol == Skyhop.Aprs.Client.Enums.Symbol.Aircraft); + Assert.IsTrue(result.TurnRate == -1.6); + Assert.AreEqual(AircraftType.Glider, result.AircraftType); + } + + [TestMethod] + public void TestOGNTowAircraftHBEXPLszxMessageParsing() + { + var message = "ICA4B0CF5>APRS,qAS,LSZX:/091131h4710.19N/00902.42E'149/007/A=001355 !W74! id094B0CF5 +020fpm +0.4rot 42.2dB 0e -3.4kHz gps3x3"; + + var result = PacketInfo.Parse(message); + + Assert.IsTrue(result != null); + Assert.IsTrue(result.Altitude.FeetAboveSeaLevel == 1355); + Assert.IsTrue(result.Callsign == "ICA4B0CF5"); + Assert.IsTrue(result.ClimbRate == 20); + Assert.IsTrue(result.DataType == Skyhop.Aprs.Client.Enums.DataType.PositionWithTimestampNoAprsMessaging); + Assert.IsTrue(result.Direction.Degrees == 149); + Assert.IsTrue(result.Latitude.AbsoluteValue == 47.16983333333333); + Assert.IsTrue(result.Longitude.AbsoluteValue == 9.0403333333333329); + Assert.IsTrue(result.MicEMessageType == Skyhop.Aprs.Client.Enums.MicEMessageType.OffDuty); + Assert.IsTrue(result.Speed.Knots == 7); + Assert.IsTrue(result.StationRoute[0] == "APRS"); + Assert.IsTrue(result.StationRoute[1] == "qAS"); + Assert.IsTrue(result.StationRoute[2] == "LSZX"); + Assert.IsTrue(result.Symbol == Skyhop.Aprs.Client.Enums.Symbol.Aircraft); + Assert.IsTrue(result.TurnRate == 0.4); + Assert.AreEqual(AircraftType.TowPlane, result.AircraftType); + } + + [TestMethod] + public void TestOGNFLRMessageParsing() + { + var message = "ICA4B3CA5>APRS,qAS,LSZX:/165008h4711.09N/00847.94E'054/079/A=004402 !W59! id054B3CA5 -157fpm +0.0rot 13.8dB 0e -1.9kHz gps1x2 +5.3dBm"; + + var result = PacketInfo.Parse(message); + + Assert.IsTrue(result != null); + Assert.IsTrue(result.Altitude.FeetAboveSeaLevel == 4402); + Assert.IsTrue(result.Callsign == "ICA4B3CA5"); + Assert.IsTrue(result.ClimbRate == -157); + Assert.IsTrue(result.DataType == Skyhop.Aprs.Client.Enums.DataType.PositionWithTimestampNoAprsMessaging); + Assert.IsTrue(result.Direction.Degrees == 54); + Assert.IsTrue(result.Latitude.AbsoluteValue == 47.18483333333333); + Assert.IsTrue(result.Longitude.AbsoluteValue == 8.799); + Assert.IsTrue(result.MicEMessageType == Skyhop.Aprs.Client.Enums.MicEMessageType.OffDuty); + Assert.IsTrue(result.Speed.Knots == 79); + Assert.IsTrue(result.StationRoute[0] == "APRS"); + Assert.IsTrue(result.StationRoute[1] == "qAS"); + Assert.IsTrue(result.StationRoute[2] == "LSZX"); + Assert.IsTrue(result.Symbol == Skyhop.Aprs.Client.Enums.Symbol.Aircraft); + Assert.IsTrue(result.TurnRate == 0); } [TestMethod] diff --git a/Skyhop.Aprs.Client/Enums/AddressType.cs b/Skyhop.Aprs.Client/Enums/AddressType.cs new file mode 100644 index 0000000..0bc82b7 --- /dev/null +++ b/Skyhop.Aprs.Client/Enums/AddressType.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Skyhop.Aprs.Client.Enums +{ + public enum AddressType + { + Random = 0x0, + ICAO = 0x1, + Flarm = 0x2, + OGN = 0x3 + } +} diff --git a/Skyhop.Aprs.Client/Enums/AircraftType.cs b/Skyhop.Aprs.Client/Enums/AircraftType.cs new file mode 100644 index 0000000..22dd461 --- /dev/null +++ b/Skyhop.Aprs.Client/Enums/AircraftType.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Skyhop.Aprs.Client.Enums +{ + public enum AircraftType + { + Unknown = 0x0, + Glider = 0x1, + TowPlane = 0x2, + Helicopter = 0x3, + Skydiver = 0x4, + DropPlane = 0x5, + Hangglider = 0x6, + Paraglider = 0x7, + PoweredPiston = 0x8, + PoweredJet = 0x9, + Unknown2 = 0xA, + Balloon = 0xB, + Airship = 0xC, + UAV = 0xD, + Unknown3 = 0xE, + Static = 0xF + } +} diff --git a/Skyhop.Aprs.Client/Models/AprsMessage.cs b/Skyhop.Aprs.Client/Models/AprsMessage.cs index b5f5ebf..9d21f59 100644 --- a/Skyhop.Aprs.Client/Models/AprsMessage.cs +++ b/Skyhop.Aprs.Client/Models/AprsMessage.cs @@ -28,6 +28,16 @@ public static AprsMessage Parse(string message) public MicEMessageType MicEMessageType { get; internal set; } public DateTime ReceivedDate { get; internal set; } + public string DeviceId { get; internal set; } + + public AircraftType AircraftType { get; internal set; } + + public AddressType AddressType { get; internal set; } + + public bool StealthMode { get; internal set; } + + public bool NoTrackingFlag { get; internal set; } + // This is specifically for OGN flavored APRS public int ClimbRate { get; internal set; } public double TurnRate { get; internal set; } @@ -54,6 +64,9 @@ public override string ToString() sb.AppendLine($"{(nameof(Speed).SplitCamelCase().PadLeft(padding))}: {Speed}"); sb.AppendLine($"{(nameof(SymbolTable).SplitCamelCase().PadLeft(padding))}: {SymbolTable}"); sb.AppendLine($"{(nameof(Symbol).SplitCamelCase().PadLeft(padding))}: {Symbol}"); + sb.AppendLine($"{(nameof(DeviceId).SplitCamelCase().PadLeft(padding))}: {DeviceId}"); + sb.AppendLine($"{(nameof(AircraftType).SplitCamelCase().PadLeft(padding))}: {AircraftType}"); + sb.AppendLine($"{(nameof(AddressType).SplitCamelCase().PadLeft(padding))}: {AddressType}"); if (DataType == DataType.CurrentMicE) sb.AppendLine($"{(nameof(MicEMessageType).SplitCamelCase().PadLeft(padding))}: {MicEMessageType}"); diff --git a/Skyhop.Aprs.Client/Models/PacketInfo.cs b/Skyhop.Aprs.Client/Models/PacketInfo.cs index 9287e19..fc7fd6b 100644 --- a/Skyhop.Aprs.Client/Models/PacketInfo.cs +++ b/Skyhop.Aprs.Client/Models/PacketInfo.cs @@ -4,6 +4,7 @@ using System; using System.Collections.ObjectModel; +using System.Globalization; using System.Linq; using System.Text; using System.Text.RegularExpressions; @@ -37,6 +38,32 @@ public static AprsMessage Parse(string rawData) if (string.IsNullOrEmpty(rawData)) return null; + // -- id bits and mask ---------------------------------------------------------------- + // according: http://wiki.glidernet.org/wiki:subscribe-to-ogn-data + // and: http://www.ediatec.ch/pdf/FLARM%20Data%20Port%20Specification%20v7.00.pdf + // idXXYYYYYY => XX encoding, YY address + + try + { + var matchAircraft = Regex.Match(rawData, @"(?:\sid)([a-fA-F0-9]{8})(?:\s)"); + + if (matchAircraft.Success) + { + aprsMessage.DeviceId = matchAircraft.Groups[1].Value.Substring(2); + var aircraftId = ulong.Parse(matchAircraft.Groups[1].Value.Trim(), NumberStyles.HexNumber); + byte addressTypeAndFlagsByte = (byte)((aircraftId & 0xFF000000) >> 24); + aprsMessage.AddressType = (AddressType)(addressTypeAndFlagsByte & 0x03); + aprsMessage.AircraftType = (AircraftType)((addressTypeAndFlagsByte & 0x3C) >> 2); + aprsMessage.StealthMode = (addressTypeAndFlagsByte & 0x80) > 0; + aprsMessage.NoTrackingFlag = (addressTypeAndFlagsByte & 0x40) > 0; + //uint aircraftAddress = (uint)(aircraftId & 0x00FFFFFF); + } + } + catch (Exception ex) + { + + } + DataType dataType; if (!Constants.Maps.DataTypeMap.TryGetValue(Convert.ToByte(rawData[0]), out dataType)) From aff210a81eb589d1bd63d74dce85c27bea7610fd Mon Sep 17 00:00:00 2001 From: pschuler78 Date: Sat, 9 Oct 2021 19:55:29 +0200 Subject: [PATCH 3/3] Removed catch variable Exception from empty handling --- Skyhop.Aprs.Client/Models/PacketInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Skyhop.Aprs.Client/Models/PacketInfo.cs b/Skyhop.Aprs.Client/Models/PacketInfo.cs index fc7fd6b..7953d41 100644 --- a/Skyhop.Aprs.Client/Models/PacketInfo.cs +++ b/Skyhop.Aprs.Client/Models/PacketInfo.cs @@ -59,7 +59,7 @@ public static AprsMessage Parse(string rawData) //uint aircraftAddress = (uint)(aircraftId & 0x00FFFFFF); } } - catch (Exception ex) + catch { }