From fbfe89c70467930bf3f8630de1f16aa8be8e0e9b Mon Sep 17 00:00:00 2001 From: Morten Nielsen Date: Sat, 1 Aug 2020 11:03:24 -0700 Subject: [PATCH] Allow skipping checksums and better handle missing checksum after `*` As discussed in #74 --- src/NmeaParser/Nmea/NmeaMessage.cs | 15 ++++++---- .../NmeaParser.Tests/NmeaMessages.cs | 28 ++++++++++++++++++- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/NmeaParser/Nmea/NmeaMessage.cs b/src/NmeaParser/Nmea/NmeaMessage.cs index 4f939b9..14db334 100644 --- a/src/NmeaParser/Nmea/NmeaMessage.cs +++ b/src/NmeaParser/Nmea/NmeaMessage.cs @@ -138,28 +138,33 @@ namespace NmeaParser.Messages /// /// The NMEA message string. /// The previously received message (only used if parsing multi-sentence messages) + /// If true ignores the checksum completely, if false validates the checksum if present. /// The nmea message that was parsed. /// /// Invalid nmea message: Missing starting character '$' /// or checksum failure /// - public static NmeaMessage Parse(string message, IMultiSentenceMessage? previousSentence = null) + public static NmeaMessage Parse(string message, IMultiSentenceMessage? previousSentence = null, bool ignoreChecksum = false) { if (string.IsNullOrEmpty(message)) throw new ArgumentNullException(nameof(message)); int checksum = -1; - if (message[0] != '$') - throw new ArgumentException("Invalid NMEA message: Missing starting character '$'"); if (message[0] != '$') throw new ArgumentException("Invalid NMEA message: Missing starting character '$'"); var idx = message.IndexOf('*'); if (idx >= 0) { - checksum = Convert.ToInt32(message.Substring(idx + 1), 16); + if (message.Length > idx + 1) + { + if (int.TryParse(message.Substring(idx + 1), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out int c)) + checksum = c; + else + throw new ArgumentException("Invalid checksum string"); + } message = message.Substring(0, message.IndexOf('*')); } - if (checksum > -1) + if (!ignoreChecksum && checksum > -1) { int checksumTest = 0; for (int i = 1; i < message.Length; i++) diff --git a/src/UnitTests/NmeaParser.Tests/NmeaMessages.cs b/src/UnitTests/NmeaParser.Tests/NmeaMessages.cs index b7dd7e7..7119721 100644 --- a/src/UnitTests/NmeaParser.Tests/NmeaMessages.cs +++ b/src/UnitTests/NmeaParser.Tests/NmeaMessages.cs @@ -97,7 +97,33 @@ namespace NmeaParser.Tests } } } - + + [TestMethod] + public void MissingChecksumAfterStar() + { + string input = "$GPRMA,A,4917.24,S,12309.57,W,1000.0,2000.0,123.4,321.0,10,E,A*"; + var msg = NmeaMessage.Parse(input); + Assert.IsNotNull(msg); + } + + [TestMethod] + public void MissingChecksum() + { + string input = "$GPRMA,A,4917.24,S,12309.57,W,1000.0,2000.0,123.4,321.0,10,E,A"; + var msg = NmeaMessage.Parse(input); + Assert.IsNotNull(msg); + } + + [TestMethod] + public void IgnoreChecksum() + { + string input = "$GPRMA,A,4917.24,S,12309.57,W,1000.0,2000.0,123.4,321.0,10,E,A*00"; + var msg = NmeaMessage.Parse(input, ignoreChecksum: true); + Assert.IsNotNull(msg); + + Assert.ThrowsException(() => NmeaMessage.Parse(input, ignoreChecksum: false)); + } + [TestMethod] public void TestGprma() {