diff --git a/src/NmeaParser/IMultiSentenceMessage.cs b/src/NmeaParser/IMultiSentenceMessage.cs
index b825393..6948d04 100644
--- a/src/NmeaParser/IMultiSentenceMessage.cs
+++ b/src/NmeaParser/IMultiSentenceMessage.cs
@@ -18,14 +18,25 @@ using System.Text;
namespace NmeaParser
{
- public interface IMultiSentenceMessage : System.Collections.IEnumerable
+ ///
+ /// Interface used for NMEA messages that span multiple sentences
+ ///
+ public interface IMultiSentenceMessage
{
- bool TryAppend(string[] values);
- bool IsComplete { get; }
- IEnumerable SerializeParts();
- }
+ ///
+ /// Attempts to append one message to an existing one
+ ///
+ ///
+ /// This method should return false if the message being appended isn't the next message in line, and various indicators show this is a different message than the previous one. It should also return false if you append to a message that didn't start with the first message.
+ ///
+ ///
+ ///
+ /// True is the message was successfully appended, False is the message couldn't be appended.
+ bool TryAppend(string messageType, string[] values);
- public interface IMultiSentenceMessage : IMultiSentenceMessage, IEnumerable
- {
+ ///
+ /// Gets a value indicating whether this message is fully loaded from all its sentences
+ ///
+ bool IsComplete { get; }
}
}
diff --git a/src/NmeaParser/Nmea/Gsv.cs b/src/NmeaParser/Nmea/Gsv.cs
index 50ad9fd..db1d5ec 100644
--- a/src/NmeaParser/Nmea/Gsv.cs
+++ b/src/NmeaParser/Nmea/Gsv.cs
@@ -24,12 +24,9 @@ namespace NmeaParser.Nmea
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gsv")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
[NmeaMessageType("--GSV")]
- public class Gsv : NmeaMessage, IMultiSentenceMessage
+ public class Gsv : NmeaMultiSentenceMessage, IEnumerable
{
private readonly List svs = new List();
- private int lastMessageNumber = 0;
- private int totalMessages;
- private readonly int firstMessageNumber;
///
/// Initializes a new instance of the class.
@@ -40,33 +37,22 @@ namespace NmeaParser.Nmea
{
if (message == null || message.Length < 3)
throw new ArgumentException("Invalid GSV", "message");
-
- totalMessages = int.Parse(message[0], CultureInfo.InvariantCulture);
- firstMessageNumber = int.Parse(message[1], CultureInfo.InvariantCulture);
- SVsInView = int.Parse(message[2], CultureInfo.InvariantCulture);
- AppendParts(message);
-
- List svs = new List();
- for (int i = 3; i < message.Length - 3; i += 4)
- {
- if (message[i].Length == 0)
- continue;
- else
- svs.Add(new SatelliteVehicle(message, i));
- }
- this.SVs = svs.AsReadOnly();
}
- bool IMultiSentenceMessage.TryAppend(string[] values) => AppendParts(values);
- bool IMultiSentenceMessage.IsComplete => firstMessageNumber == 1 && lastMessageNumber == totalMessages;
+ ///
+ protected override int MessageCountIndex => 0;
- private bool AppendParts(string[] message)
+ ///
+ protected override int MessageNumberIndex => 1;
+
+ ///
+ protected override bool ParseSentences(Talker talkerType, string[] message)
{
- int msgCount = int.Parse(message[0], CultureInfo.InvariantCulture);
- int msgNumber = int.Parse(message[1], CultureInfo.InvariantCulture);
var satellites = int.Parse(message[2], CultureInfo.InvariantCulture);
- if (msgCount != totalMessages || msgNumber != lastMessageNumber + 1 || satellites != SVsInView)
+ if (SVsInView == -1)
+ SVsInView = satellites;
+ else if ( satellites != SVsInView)
return false; // Messages do not match
for (int i = 3; i < message.Length - 3; i += 4)
@@ -74,27 +60,20 @@ namespace NmeaParser.Nmea
if (message[i].Length == 0)
continue;
else
- svs.Add(new SatelliteVehicle(message, i));
+ svs.Add(new SatelliteVehicle(talkerType, message, i));
}
- lastMessageNumber = msgNumber;
- this.SVs = svs.AsReadOnly();
return true;
}
- IEnumerable IMultiSentenceMessage.SerializeParts()
- {
- throw new NotImplementedException();
- }
-
///
/// Total number of SVs in view
///
- public int SVsInView { get; }
+ public int SVsInView { get; private set; } = -1;
///
/// Satellite vehicles in this message part.
///
- public IReadOnlyList SVs { get; private set; }
+ public IReadOnlyList SVs => svs.AsReadOnly();
///
/// Returns an enumerator that iterates through the collection.
@@ -120,7 +99,7 @@ namespace NmeaParser.Nmea
///
public sealed class SatelliteVehicle
{
- internal SatelliteVehicle(string[] message, int startIndex)
+ internal SatelliteVehicle(Talker talker, string[] message, int startIndex)
{
PrnNumber = int.Parse(message[startIndex], CultureInfo.InvariantCulture);
if (double.TryParse(message[startIndex + 1], NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out double e))
@@ -130,19 +109,29 @@ namespace NmeaParser.Nmea
int snr = -1;
if (int.TryParse(message[startIndex + 3], out snr))
SignalToNoiseRatio = snr;
+ TalkerId = talker;
}
+
+ ///
+ /// Gets the talker ID for this vehicle
+ ///
+ public Talker TalkerId { get; }
+
///
/// SV PRN number
///
public int PrnNumber { get; }
+
///
/// Elevation in degrees, 90 maximum
///
public double Elevation { get; } = double.NaN;
+
///
/// Azimuth, degrees from true north, 000 to 359
///
public double Azimuth { get; } = double.NaN;
+
///
/// Signal-to-Noise ratio, 0-99 dB (-1 when not tracking)
///
diff --git a/src/NmeaParser/Nmea/NmeaMessage.cs b/src/NmeaParser/Nmea/NmeaMessage.cs
index 52ebbaf..076b484 100644
--- a/src/NmeaParser/Nmea/NmeaMessage.cs
+++ b/src/NmeaParser/Nmea/NmeaMessage.cs
@@ -87,6 +87,7 @@ namespace NmeaParser.Nmea
/// Parses the specified NMEA message.
///
/// The NMEA message string.
+ /// The previously received message (only used if parsing multi-sentence messages)
///
///
/// Invalid nmea message: Missing starting character '$'
@@ -120,9 +121,9 @@ namespace NmeaParser.Nmea
string[] parts = message.Split(new char[] { ',' });
string MessageType = parts[0].Substring(1);
string[] MessageParts = parts.Skip(1).ToArray();
- if(previousSentence is NmeaMessage pmsg && pmsg.MessageType == MessageType)
+ if(previousSentence is NmeaMessage pmsg && pmsg.MessageType.Substring(2) == MessageType.Substring(2))
{
- if (previousSentence.TryAppend(MessageParts))
+ if (previousSentence.TryAppend(MessageType, MessageParts))
{
return pmsg;
}
@@ -154,7 +155,7 @@ namespace NmeaParser.Nmea
///
/// Gets the talker ID for this message (
///
- public Talker TalkerId => TalkerHelper.GetTalker(MessageType);
+ public virtual Talker TalkerId => TalkerHelper.GetTalker(MessageType);
///
/// Gets a value indicating whether this message type is proprietary
@@ -175,24 +176,23 @@ namespace NmeaParser.Nmea
///
/// Gets the checksum value of the message.
///
- public byte Checksum
- {
- get
- {
- int checksumTest = 0;
- for (int j = -1; j < MessageParts.Count; j++)
- {
- string message = j < 0 ? MessageType : MessageParts[j];
- if (j >= 0)
- checksumTest ^= 0x2C; //Comma separator
- for (int i = 0; i < message.Length; i++)
- {
- checksumTest ^= Convert.ToByte(message[i]);
- }
- }
- return Convert.ToByte(checksumTest);
- }
- }
+ public byte Checksum => GetChecksum(MessageType, MessageParts);
+
+ internal static byte GetChecksum(string messageType, IReadOnlyList messageParts)
+ {
+ int checksumTest = 0;
+ for (int j = -1; j < messageParts.Count; j++)
+ {
+ string message = j < 0 ? messageType : messageParts[j];
+ if (j >= 0)
+ checksumTest ^= 0x2C; //Comma separator
+ for (int i = 0; i < message.Length; i++)
+ {
+ checksumTest ^= Convert.ToByte(message[i]);
+ }
+ }
+ return Convert.ToByte(checksumTest);
+ }
internal static double StringToLatitude(string value, string ns)
{
diff --git a/src/NmeaParser/Nmea/NmeaMultiSentenceMessage.cs b/src/NmeaParser/Nmea/NmeaMultiSentenceMessage.cs
new file mode 100644
index 0000000..a646a36
--- /dev/null
+++ b/src/NmeaParser/Nmea/NmeaMultiSentenceMessage.cs
@@ -0,0 +1,116 @@
+// *******************************************************************************
+// * Licensed under the Apache License, Version 2.0 (the "License");
+// * you may not use this file except in compliance with the License.
+// * You may obtain a copy of the License at
+// *
+// * http://www.apache.org/licenses/LICENSE-2.0
+// *
+// * Unless required by applicable law or agreed to in writing, software
+// * distributed under the License is distributed on an "AS IS" BASIS,
+// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// * See the License for the specific language governing permissions and
+// * limitations under the License.
+// ******************************************************************************
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+
+namespace NmeaParser.Nmea
+{
+ ///
+ /// Base class for easily creating message that are spread across multiple sentences
+ ///
+ public abstract class NmeaMultiSentenceMessage : NmeaMessage, IMultiSentenceMessage
+ {
+ private int lastMessageNumber = 0;
+ private int totalMessages;
+ private readonly int firstMessageNumber;
+ private readonly List messages = new List();
+ private readonly bool initialized;
+
+ ///
+ /// Initializes an instance of the class.
+ ///
+ /// Type
+ /// Message values
+ protected NmeaMultiSentenceMessage(string messageType, string[] messageParts) : base(messageType, messageParts)
+ {
+ totalMessages = int.Parse(messageParts[MessageCountIndex], CultureInfo.InvariantCulture);
+ firstMessageNumber = int.Parse(messageParts[MessageNumberIndex], CultureInfo.InvariantCulture);
+ talkerId = base.TalkerId;
+ if (!((IMultiSentenceMessage)this).TryAppend(messageType, messageParts))
+ throw new ArgumentException("Failed to parse message");
+ initialized = true;
+ }
+
+ ///
+ /// Gets the index in the where the total count of messages is listed.
+ ///
+ protected virtual int MessageCountIndex { get; } = 0;
+
+ ///
+ /// Gets the index in the where the message number is listed.
+ ///
+ protected virtual int MessageNumberIndex { get; } = 1;
+
+ bool IMultiSentenceMessage.IsComplete => firstMessageNumber == 1 && lastMessageNumber == totalMessages;
+
+ ///
+ public override string ToString()
+ {
+ System.Text.StringBuilder sb = new System.Text.StringBuilder();
+ foreach (var msg in messages)
+ {
+ if (sb.Length > 0)
+ sb.Append("\r\n");
+ sb.AppendFormat(CultureInfo.InvariantCulture, "${0},{1}*{2:X2}", MessageType, string.Join(",", msg), Checksum);
+ }
+ return sb.ToString();
+ }
+
+ bool IMultiSentenceMessage.TryAppend(string messageType, string[] message)
+ {
+ if (message == null || message.Length < Math.Max(MessageCountIndex, MessageNumberIndex))
+ throw new ArgumentException("Invalid message", "message");
+
+
+ int msgCount = int.Parse(message[0], CultureInfo.InvariantCulture);
+ int msgNumber = int.Parse(message[1], CultureInfo.InvariantCulture);
+
+ if (initialized)
+ {
+ if (firstMessageNumber != 1) //We can only append to message who has message number 1
+ return false;
+ if (msgCount != totalMessages || msgNumber != lastMessageNumber + 1)
+ return false; // Messages do not match
+ }
+
+ var talker = TalkerHelper.GetTalker(messageType);
+ if (talkerId != talker)
+ talkerId = Talker.Multiple;
+ if (ParseSentences(talker, message))
+ {
+ lastMessageNumber = msgNumber;
+ messages.Add(message);
+ return true;
+ }
+ return false;
+ }
+
+ ///
+ /// Parses the messages or any message being appended. False should be returned if it's a message being appended doesn't appear to match what has already been loded.
+ ///
+ ///
+ ///
+ /// True if the message could succesfully be appended.
+ protected abstract bool ParseSentences(Talker talkerType, string[] message);
+
+ private Talker talkerId;
+
+
+ ///
+ public override Talker TalkerId => talkerId;
+
+ }
+}
diff --git a/src/NmeaParser/Nmea/Rte.cs b/src/NmeaParser/Nmea/Rte.cs
index 0ae1af8..8dcbbc3 100644
--- a/src/NmeaParser/Nmea/Rte.cs
+++ b/src/NmeaParser/Nmea/Rte.cs
@@ -32,8 +32,10 @@ namespace NmeaParser.Nmea
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gprte")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
[NmeaMessageType("--RTE")]
- public sealed class Rte : NmeaMessage, IMultiPartMessage
+ public sealed class Rte : NmeaMultiSentenceMessage, IEnumerable
{
+ private readonly List _waypoints = new List();
+
///
/// Waypoint tpe
///
@@ -58,23 +60,18 @@ namespace NmeaParser.Nmea
{
if (message == null || message.Length < 4)
throw new ArgumentException("Invalid GPRTE", "message");
-
- TotalMessages = int.Parse(message[0], CultureInfo.InvariantCulture);
- MessageNumber = int.Parse(message[1], CultureInfo.InvariantCulture);
ListType = message[2] == "c" ? WaypointListType.CompleteWaypointsList : WaypointListType.RemainingWaypointsList;
RouteId = message[3];
- Waypoints = message.Skip(4).ToArray();
}
- ///
- /// Total number of messages of this type in this cycle
- ///
- public int TotalMessages { get; }
-
- ///
- /// Message number
- ///
- public int MessageNumber { get; }
+ ///
+ protected override bool ParseSentences(Talker talker, string[] message)
+ {
+ if (MessageParts[2] != message[2] || MessageParts[3] != message[3])
+ return false;
+ _waypoints.AddRange(message.Skip(4));
+ return true;
+ }
///
/// Gets the type of the list.
@@ -89,7 +86,7 @@ namespace NmeaParser.Nmea
///
/// Waypoints
///
- public IReadOnlyList Waypoints { get; }
+ public IReadOnlyList Waypoints => _waypoints.AsReadOnly();
///
/// Returns an enumerator that iterates through the collection.
diff --git a/src/NmeaParser/Nmea/Talker.cs b/src/NmeaParser/Nmea/Talker.cs
index 134494f..48e99e7 100644
--- a/src/NmeaParser/Nmea/Talker.cs
+++ b/src/NmeaParser/Nmea/Talker.cs
@@ -114,10 +114,14 @@ namespace NmeaParser.Nmea
///
public enum Talker
{
+ ///
+ /// Multiple talker IDs sometimes seen in
+ ///
+ Multiple = -2,
///
/// Unrecognized Talker ID
///
- Unknown,
+ Unknown = -1,
/// Independent AIS Base Station
IndependentAISBaseStation, // = AB
/// Dependent AIS Base Station
diff --git a/src/NmeaParser/NmeaDevice.cs b/src/NmeaParser/NmeaDevice.cs
index 992cccb..b0b1ed4 100644
--- a/src/NmeaParser/NmeaDevice.cs
+++ b/src/NmeaParser/NmeaDevice.cs
@@ -184,9 +184,9 @@ namespace NmeaParser
{
_lastMultiMessage = multi; //Keep it around until next time
return;
- }
- _lastMultiMessage = null;
+ }
}
+ _lastMultiMessage = null;
if (msg != null)
OnMessageReceived(msg);
}
@@ -284,21 +284,5 @@ namespace NmeaParser
/// The nmea message.
///
public Nmea.NmeaMessage Message { get; }
-
- ///
- /// Gets a value indicating whether this instance is a multi part message.
- ///
- ///
- /// true if this instance is multi part; otherwise, false.
- ///
- public bool IsMultipart => Message is IMultiSentenceMessage;
-
- ///
- /// Gets the message parts if this is a multi-part message and all message parts has been received.
- ///
- ///
- /// The message parts.
- ///
- public IReadOnlyList? MessageParts { get; }
}
}
diff --git a/src/SampleApp.Droid/Resources/Resource.Designer.cs b/src/SampleApp.Droid/Resources/Resource.Designer.cs
index c146640..1084f06 100644
--- a/src/SampleApp.Droid/Resources/Resource.Designer.cs
+++ b/src/SampleApp.Droid/Resources/Resource.Designer.cs
@@ -31,31 +31,31 @@ namespace SampleApp.Droid
public partial class Attribute
{
- // aapt resource value: 0x7f010007
- public const int font = 2130771975;
+ // aapt resource value: 0x7F010000
+ public const int font = 2130771968;
- // aapt resource value: 0x7f010000
- public const int fontProviderAuthority = 2130771968;
+ // aapt resource value: 0x7F010001
+ public const int fontProviderAuthority = 2130771969;
- // aapt resource value: 0x7f010003
- public const int fontProviderCerts = 2130771971;
+ // aapt resource value: 0x7F010002
+ public const int fontProviderCerts = 2130771970;
- // aapt resource value: 0x7f010004
- public const int fontProviderFetchStrategy = 2130771972;
+ // aapt resource value: 0x7F010003
+ public const int fontProviderFetchStrategy = 2130771971;
- // aapt resource value: 0x7f010005
- public const int fontProviderFetchTimeout = 2130771973;
+ // aapt resource value: 0x7F010004
+ public const int fontProviderFetchTimeout = 2130771972;
- // aapt resource value: 0x7f010001
- public const int fontProviderPackage = 2130771969;
+ // aapt resource value: 0x7F010005
+ public const int fontProviderPackage = 2130771973;
- // aapt resource value: 0x7f010002
- public const int fontProviderQuery = 2130771970;
+ // aapt resource value: 0x7F010006
+ public const int fontProviderQuery = 2130771974;
- // aapt resource value: 0x7f010006
- public const int fontStyle = 2130771974;
+ // aapt resource value: 0x7F010007
+ public const int fontStyle = 2130771975;
- // aapt resource value: 0x7f010008
+ // aapt resource value: 0x7F010008
public const int fontWeight = 2130771976;
static Attribute()
@@ -71,8 +71,8 @@ namespace SampleApp.Droid
public partial class Boolean
{
- // aapt resource value: 0x7f080000
- public const int abc_action_bar_embed_tabs = 2131230720;
+ // aapt resource value: 0x7F020000
+ public const int abc_action_bar_embed_tabs = 2130837504;
static Boolean()
{
@@ -87,26 +87,26 @@ namespace SampleApp.Droid
public partial class Color
{
- // aapt resource value: 0x7f050003
- public const int notification_action_color_filter = 2131034115;
+ // aapt resource value: 0x7F030000
+ public const int notification_action_color_filter = 2130903040;
- // aapt resource value: 0x7f050004
- public const int notification_icon_bg_color = 2131034116;
+ // aapt resource value: 0x7F030001
+ public const int notification_icon_bg_color = 2130903041;
- // aapt resource value: 0x7f050000
- public const int notification_material_background_media_default_color = 2131034112;
+ // aapt resource value: 0x7F030002
+ public const int notification_material_background_media_default_color = 2130903042;
- // aapt resource value: 0x7f050001
- public const int primary_text_default_material_dark = 2131034113;
+ // aapt resource value: 0x7F030003
+ public const int primary_text_default_material_dark = 2130903043;
- // aapt resource value: 0x7f050005
- public const int ripple_material_light = 2131034117;
+ // aapt resource value: 0x7F030004
+ public const int ripple_material_light = 2130903044;
- // aapt resource value: 0x7f050002
- public const int secondary_text_default_material_dark = 2131034114;
+ // aapt resource value: 0x7F030005
+ public const int secondary_text_default_material_dark = 2130903045;
- // aapt resource value: 0x7f050006
- public const int secondary_text_default_material_light = 2131034118;
+ // aapt resource value: 0x7F030006
+ public const int secondary_text_default_material_light = 2130903046;
static Color()
{
@@ -121,65 +121,65 @@ namespace SampleApp.Droid
public partial class Dimension
{
- // aapt resource value: 0x7f090004
- public const int compat_button_inset_horizontal_material = 2131296260;
+ // aapt resource value: 0x7F040000
+ public const int compat_button_inset_horizontal_material = 2130968576;
- // aapt resource value: 0x7f090005
- public const int compat_button_inset_vertical_material = 2131296261;
+ // aapt resource value: 0x7F040001
+ public const int compat_button_inset_vertical_material = 2130968577;
- // aapt resource value: 0x7f090006
- public const int compat_button_padding_horizontal_material = 2131296262;
+ // aapt resource value: 0x7F040002
+ public const int compat_button_padding_horizontal_material = 2130968578;
- // aapt resource value: 0x7f090007
- public const int compat_button_padding_vertical_material = 2131296263;
+ // aapt resource value: 0x7F040003
+ public const int compat_button_padding_vertical_material = 2130968579;
- // aapt resource value: 0x7f090008
- public const int compat_control_corner_material = 2131296264;
+ // aapt resource value: 0x7F040004
+ public const int compat_control_corner_material = 2130968580;
- // aapt resource value: 0x7f090009
- public const int notification_action_icon_size = 2131296265;
+ // aapt resource value: 0x7F040005
+ public const int notification_action_icon_size = 2130968581;
- // aapt resource value: 0x7f09000a
- public const int notification_action_text_size = 2131296266;
+ // aapt resource value: 0x7F040006
+ public const int notification_action_text_size = 2130968582;
- // aapt resource value: 0x7f09000b
- public const int notification_big_circle_margin = 2131296267;
+ // aapt resource value: 0x7F040007
+ public const int notification_big_circle_margin = 2130968583;
- // aapt resource value: 0x7f090001
- public const int notification_content_margin_start = 2131296257;
+ // aapt resource value: 0x7F040008
+ public const int notification_content_margin_start = 2130968584;
- // aapt resource value: 0x7f09000c
- public const int notification_large_icon_height = 2131296268;
+ // aapt resource value: 0x7F040009
+ public const int notification_large_icon_height = 2130968585;
- // aapt resource value: 0x7f09000d
- public const int notification_large_icon_width = 2131296269;
+ // aapt resource value: 0x7F04000A
+ public const int notification_large_icon_width = 2130968586;
- // aapt resource value: 0x7f090002
- public const int notification_main_column_padding_top = 2131296258;
+ // aapt resource value: 0x7F04000B
+ public const int notification_main_column_padding_top = 2130968587;
- // aapt resource value: 0x7f090003
- public const int notification_media_narrow_margin = 2131296259;
+ // aapt resource value: 0x7F04000C
+ public const int notification_media_narrow_margin = 2130968588;
- // aapt resource value: 0x7f09000e
- public const int notification_right_icon_size = 2131296270;
+ // aapt resource value: 0x7F04000D
+ public const int notification_right_icon_size = 2130968589;
- // aapt resource value: 0x7f090000
- public const int notification_right_side_padding_top = 2131296256;
+ // aapt resource value: 0x7F04000E
+ public const int notification_right_side_padding_top = 2130968590;
- // aapt resource value: 0x7f09000f
- public const int notification_small_icon_background_padding = 2131296271;
+ // aapt resource value: 0x7F04000F
+ public const int notification_small_icon_background_padding = 2130968591;
- // aapt resource value: 0x7f090010
- public const int notification_small_icon_size_as_large = 2131296272;
+ // aapt resource value: 0x7F040010
+ public const int notification_small_icon_size_as_large = 2130968592;
- // aapt resource value: 0x7f090011
- public const int notification_subtext_size = 2131296273;
+ // aapt resource value: 0x7F040011
+ public const int notification_subtext_size = 2130968593;
- // aapt resource value: 0x7f090012
- public const int notification_top_pad = 2131296274;
+ // aapt resource value: 0x7F040012
+ public const int notification_top_pad = 2130968594;
- // aapt resource value: 0x7f090013
- public const int notification_top_pad_large_text = 2131296275;
+ // aapt resource value: 0x7F040013
+ public const int notification_top_pad_large_text = 2130968595;
static Dimension()
{
@@ -194,41 +194,41 @@ namespace SampleApp.Droid
public partial class Drawable
{
- // aapt resource value: 0x7f020000
- public const int notification_action_background = 2130837504;
+ // aapt resource value: 0x7F050000
+ public const int notification_action_background = 2131034112;
- // aapt resource value: 0x7f020001
- public const int notification_bg = 2130837505;
+ // aapt resource value: 0x7F050001
+ public const int notification_bg = 2131034113;
- // aapt resource value: 0x7f020002
- public const int notification_bg_low = 2130837506;
+ // aapt resource value: 0x7F050002
+ public const int notification_bg_low = 2131034114;
- // aapt resource value: 0x7f020003
- public const int notification_bg_low_normal = 2130837507;
+ // aapt resource value: 0x7F050003
+ public const int notification_bg_low_normal = 2131034115;
- // aapt resource value: 0x7f020004
- public const int notification_bg_low_pressed = 2130837508;
+ // aapt resource value: 0x7F050004
+ public const int notification_bg_low_pressed = 2131034116;
- // aapt resource value: 0x7f020005
- public const int notification_bg_normal = 2130837509;
+ // aapt resource value: 0x7F050005
+ public const int notification_bg_normal = 2131034117;
- // aapt resource value: 0x7f020006
- public const int notification_bg_normal_pressed = 2130837510;
+ // aapt resource value: 0x7F050006
+ public const int notification_bg_normal_pressed = 2131034118;
- // aapt resource value: 0x7f020007
- public const int notification_icon_background = 2130837511;
+ // aapt resource value: 0x7F050007
+ public const int notification_icon_background = 2131034119;
- // aapt resource value: 0x7f02000a
- public const int notification_template_icon_bg = 2130837514;
+ // aapt resource value: 0x7F050008
+ public const int notification_template_icon_bg = 2131034120;
- // aapt resource value: 0x7f02000b
- public const int notification_template_icon_low_bg = 2130837515;
+ // aapt resource value: 0x7F050009
+ public const int notification_template_icon_low_bg = 2131034121;
- // aapt resource value: 0x7f020008
- public const int notification_tile_bg = 2130837512;
+ // aapt resource value: 0x7F05000A
+ public const int notification_tile_bg = 2131034122;
- // aapt resource value: 0x7f020009
- public const int notify_panel_notification_icon_bg = 2130837513;
+ // aapt resource value: 0x7F05000B
+ public const int notify_panel_notification_icon_bg = 2131034123;
static Drawable()
{
@@ -243,119 +243,119 @@ namespace SampleApp.Droid
public partial class Id
{
- // aapt resource value: 0x7f0a0015
- public const int action0 = 2131361813;
+ // aapt resource value: 0x7F060000
+ public const int action0 = 2131099648;
- // aapt resource value: 0x7f0a0012
- public const int action_container = 2131361810;
+ // aapt resource value: 0x7F060005
+ public const int actions = 2131099653;
- // aapt resource value: 0x7f0a0019
- public const int action_divider = 2131361817;
+ // aapt resource value: 0x7F060001
+ public const int action_container = 2131099649;
- // aapt resource value: 0x7f0a0013
- public const int action_image = 2131361811;
+ // aapt resource value: 0x7F060002
+ public const int action_divider = 2131099650;
- // aapt resource value: 0x7f0a0014
- public const int action_text = 2131361812;
+ // aapt resource value: 0x7F060003
+ public const int action_image = 2131099651;
- // aapt resource value: 0x7f0a0023
- public const int actions = 2131361827;
+ // aapt resource value: 0x7F060004
+ public const int action_text = 2131099652;
- // aapt resource value: 0x7f0a000d
- public const int altitude = 2131361805;
+ // aapt resource value: 0x7F060006
+ public const int altitude = 2131099654;
- // aapt resource value: 0x7f0a0006
- public const int async = 2131361798;
+ // aapt resource value: 0x7F060007
+ public const int async = 2131099655;
- // aapt resource value: 0x7f0a0007
- public const int blocking = 2131361799;
+ // aapt resource value: 0x7F060008
+ public const int blocking = 2131099656;
- // aapt resource value: 0x7f0a0016
- public const int cancel_action = 2131361814;
+ // aapt resource value: 0x7F060009
+ public const int cancel_action = 2131099657;
- // aapt resource value: 0x7f0a001e
- public const int chronometer = 2131361822;
+ // aapt resource value: 0x7F06000A
+ public const int chronometer = 2131099658;
- // aapt resource value: 0x7f0a000e
- public const int device_picker = 2131361806;
+ // aapt resource value: 0x7F06000B
+ public const int device_picker = 2131099659;
- // aapt resource value: 0x7f0a0025
- public const int end_padder = 2131361829;
+ // aapt resource value: 0x7F06000C
+ public const int end_padder = 2131099660;
- // aapt resource value: 0x7f0a0008
- public const int forever = 2131361800;
+ // aapt resource value: 0x7F06000D
+ public const int forever = 2131099661;
- // aapt resource value: 0x7f0a0020
- public const int icon = 2131361824;
+ // aapt resource value: 0x7F06000E
+ public const int icon = 2131099662;
- // aapt resource value: 0x7f0a0024
- public const int icon_group = 2131361828;
+ // aapt resource value: 0x7F06000F
+ public const int icon_group = 2131099663;
- // aapt resource value: 0x7f0a001f
- public const int info = 2131361823;
+ // aapt resource value: 0x7F060010
+ public const int info = 2131099664;
- // aapt resource value: 0x7f0a0009
- public const int italic = 2131361801;
+ // aapt resource value: 0x7F060011
+ public const int italic = 2131099665;
- // aapt resource value: 0x7f0a000c
- public const int latitude = 2131361804;
+ // aapt resource value: 0x7F060012
+ public const int latitude = 2131099666;
- // aapt resource value: 0x7f0a0000
- public const int line1 = 2131361792;
+ // aapt resource value: 0x7F060013
+ public const int line1 = 2131099667;
- // aapt resource value: 0x7f0a0001
- public const int line3 = 2131361793;
+ // aapt resource value: 0x7F060014
+ public const int line3 = 2131099668;
- // aapt resource value: 0x7f0a000b
- public const int longitude = 2131361803;
+ // aapt resource value: 0x7F060015
+ public const int longitude = 2131099669;
- // aapt resource value: 0x7f0a0018
- public const int media_actions = 2131361816;
+ // aapt resource value: 0x7F060016
+ public const int media_actions = 2131099670;
- // aapt resource value: 0x7f0a000a
- public const int normal = 2131361802;
+ // aapt resource value: 0x7F060017
+ public const int normal = 2131099671;
- // aapt resource value: 0x7f0a0022
- public const int notification_background = 2131361826;
+ // aapt resource value: 0x7F060018
+ public const int notification_background = 2131099672;
- // aapt resource value: 0x7f0a001b
- public const int notification_main_column = 2131361819;
+ // aapt resource value: 0x7F060019
+ public const int notification_main_column = 2131099673;
- // aapt resource value: 0x7f0a001a
- public const int notification_main_column_container = 2131361818;
+ // aapt resource value: 0x7F06001A
+ public const int notification_main_column_container = 2131099674;
- // aapt resource value: 0x7f0a0011
- public const int output = 2131361809;
+ // aapt resource value: 0x7F06001B
+ public const int output = 2131099675;
- // aapt resource value: 0x7f0a0021
- public const int right_icon = 2131361825;
+ // aapt resource value: 0x7F06001C
+ public const int right_icon = 2131099676;
- // aapt resource value: 0x7f0a001c
- public const int right_side = 2131361820;
+ // aapt resource value: 0x7F06001D
+ public const int right_side = 2131099677;
- // aapt resource value: 0x7f0a000f
- public const int startButton = 2131361807;
+ // aapt resource value: 0x7F06001E
+ public const int startButton = 2131099678;
- // aapt resource value: 0x7f0a0017
- public const int status_bar_latest_event_content = 2131361815;
+ // aapt resource value: 0x7F06001F
+ public const int status_bar_latest_event_content = 2131099679;
- // aapt resource value: 0x7f0a0010
- public const int stopButton = 2131361808;
+ // aapt resource value: 0x7F060020
+ public const int stopButton = 2131099680;
- // aapt resource value: 0x7f0a0002
- public const int tag_transition_group = 2131361794;
+ // aapt resource value: 0x7F060021
+ public const int tag_transition_group = 2131099681;
- // aapt resource value: 0x7f0a0003
- public const int text = 2131361795;
+ // aapt resource value: 0x7F060022
+ public const int text = 2131099682;
- // aapt resource value: 0x7f0a0004
- public const int text2 = 2131361796;
+ // aapt resource value: 0x7F060023
+ public const int text2 = 2131099683;
- // aapt resource value: 0x7f0a001d
- public const int time = 2131361821;
+ // aapt resource value: 0x7F060024
+ public const int time = 2131099684;
- // aapt resource value: 0x7f0a0005
- public const int title = 2131361797;
+ // aapt resource value: 0x7F060025
+ public const int title = 2131099685;
static Id()
{
@@ -370,11 +370,11 @@ namespace SampleApp.Droid
public partial class Integer
{
- // aapt resource value: 0x7f060000
- public const int cancel_button_image_alpha = 2131099648;
+ // aapt resource value: 0x7F070000
+ public const int cancel_button_image_alpha = 2131165184;
- // aapt resource value: 0x7f060001
- public const int status_bar_notification_info_maxnum = 2131099649;
+ // aapt resource value: 0x7F070001
+ public const int status_bar_notification_info_maxnum = 2131165185;
static Integer()
{
@@ -389,53 +389,53 @@ namespace SampleApp.Droid
public partial class Layout
{
- // aapt resource value: 0x7f030000
- public const int Main = 2130903040;
+ // aapt resource value: 0x7F080000
+ public const int Main = 2131230720;
- // aapt resource value: 0x7f030001
- public const int notification_action = 2130903041;
+ // aapt resource value: 0x7F080001
+ public const int notification_action = 2131230721;
- // aapt resource value: 0x7f030002
- public const int notification_action_tombstone = 2130903042;
+ // aapt resource value: 0x7F080002
+ public const int notification_action_tombstone = 2131230722;
- // aapt resource value: 0x7f030003
- public const int notification_media_action = 2130903043;
+ // aapt resource value: 0x7F080003
+ public const int notification_media_action = 2131230723;
- // aapt resource value: 0x7f030004
- public const int notification_media_cancel_action = 2130903044;
+ // aapt resource value: 0x7F080004
+ public const int notification_media_cancel_action = 2131230724;
- // aapt resource value: 0x7f030005
- public const int notification_template_big_media = 2130903045;
+ // aapt resource value: 0x7F080005
+ public const int notification_template_big_media = 2131230725;
- // aapt resource value: 0x7f030006
- public const int notification_template_big_media_custom = 2130903046;
+ // aapt resource value: 0x7F080006
+ public const int notification_template_big_media_custom = 2131230726;
- // aapt resource value: 0x7f030007
- public const int notification_template_big_media_narrow = 2130903047;
+ // aapt resource value: 0x7F080007
+ public const int notification_template_big_media_narrow = 2131230727;
- // aapt resource value: 0x7f030008
- public const int notification_template_big_media_narrow_custom = 2130903048;
+ // aapt resource value: 0x7F080008
+ public const int notification_template_big_media_narrow_custom = 2131230728;
- // aapt resource value: 0x7f030009
- public const int notification_template_custom_big = 2130903049;
+ // aapt resource value: 0x7F080009
+ public const int notification_template_custom_big = 2131230729;
- // aapt resource value: 0x7f03000a
- public const int notification_template_icon_group = 2130903050;
+ // aapt resource value: 0x7F08000A
+ public const int notification_template_icon_group = 2131230730;
- // aapt resource value: 0x7f03000b
- public const int notification_template_lines_media = 2130903051;
+ // aapt resource value: 0x7F08000B
+ public const int notification_template_lines_media = 2131230731;
- // aapt resource value: 0x7f03000c
- public const int notification_template_media = 2130903052;
+ // aapt resource value: 0x7F08000C
+ public const int notification_template_media = 2131230732;
- // aapt resource value: 0x7f03000d
- public const int notification_template_media_custom = 2130903053;
+ // aapt resource value: 0x7F08000D
+ public const int notification_template_media_custom = 2131230733;
- // aapt resource value: 0x7f03000e
- public const int notification_template_part_chronometer = 2130903054;
+ // aapt resource value: 0x7F08000E
+ public const int notification_template_part_chronometer = 2131230734;
- // aapt resource value: 0x7f03000f
- public const int notification_template_part_time = 2130903055;
+ // aapt resource value: 0x7F08000F
+ public const int notification_template_part_time = 2131230735;
static Layout()
{
@@ -450,11 +450,11 @@ namespace SampleApp.Droid
public partial class String
{
- // aapt resource value: 0x7f070001
- public const int app_name = 2131165185;
+ // aapt resource value: 0x7F090000
+ public const int app_name = 2131296256;
- // aapt resource value: 0x7f070000
- public const int status_bar_notification_info_overflow = 2131165184;
+ // aapt resource value: 0x7F090001
+ public const int status_bar_notification_info_overflow = 2131296257;
static String()
{
@@ -469,41 +469,41 @@ namespace SampleApp.Droid
public partial class Style
{
- // aapt resource value: 0x7f040005
- public const int TextAppearance_Compat_Notification = 2130968581;
+ // aapt resource value: 0x7F0A0000
+ public const int TextAppearance_Compat_Notification = 2131361792;
- // aapt resource value: 0x7f040006
- public const int TextAppearance_Compat_Notification_Info = 2130968582;
+ // aapt resource value: 0x7F0A0001
+ public const int TextAppearance_Compat_Notification_Info = 2131361793;
- // aapt resource value: 0x7f040000
- public const int TextAppearance_Compat_Notification_Info_Media = 2130968576;
+ // aapt resource value: 0x7F0A0002
+ public const int TextAppearance_Compat_Notification_Info_Media = 2131361794;
- // aapt resource value: 0x7f04000b
- public const int TextAppearance_Compat_Notification_Line2 = 2130968587;
+ // aapt resource value: 0x7F0A0003
+ public const int TextAppearance_Compat_Notification_Line2 = 2131361795;
- // aapt resource value: 0x7f040004
- public const int TextAppearance_Compat_Notification_Line2_Media = 2130968580;
+ // aapt resource value: 0x7F0A0004
+ public const int TextAppearance_Compat_Notification_Line2_Media = 2131361796;
- // aapt resource value: 0x7f040001
- public const int TextAppearance_Compat_Notification_Media = 2130968577;
+ // aapt resource value: 0x7F0A0005
+ public const int TextAppearance_Compat_Notification_Media = 2131361797;
- // aapt resource value: 0x7f040007
- public const int TextAppearance_Compat_Notification_Time = 2130968583;
+ // aapt resource value: 0x7F0A0006
+ public const int TextAppearance_Compat_Notification_Time = 2131361798;
- // aapt resource value: 0x7f040002
- public const int TextAppearance_Compat_Notification_Time_Media = 2130968578;
+ // aapt resource value: 0x7F0A0007
+ public const int TextAppearance_Compat_Notification_Time_Media = 2131361799;
- // aapt resource value: 0x7f040008
- public const int TextAppearance_Compat_Notification_Title = 2130968584;
+ // aapt resource value: 0x7F0A0008
+ public const int TextAppearance_Compat_Notification_Title = 2131361800;
- // aapt resource value: 0x7f040003
- public const int TextAppearance_Compat_Notification_Title_Media = 2130968579;
+ // aapt resource value: 0x7F0A0009
+ public const int TextAppearance_Compat_Notification_Title_Media = 2131361801;
- // aapt resource value: 0x7f040009
- public const int Widget_Compat_NotificationActionContainer = 2130968585;
+ // aapt resource value: 0x7F0A000A
+ public const int Widget_Compat_NotificationActionContainer = 2131361802;
- // aapt resource value: 0x7f04000a
- public const int Widget_Compat_NotificationActionText = 2130968586;
+ // aapt resource value: 0x7F0A000B
+ public const int Widget_Compat_NotificationActionText = 2131361803;
static Style()
{
@@ -518,37 +518,21 @@ namespace SampleApp.Droid
public partial class Styleable
{
+ // aapt resource value: { 0x7F010001,0x7F010002,0x7F010003,0x7F010004,0x7F010005,0x7F010006 }
public static int[] FontFamily = new int[] {
- 2130771968,
2130771969,
2130771970,
2130771971,
2130771972,
- 2130771973};
-
- // aapt resource value: 0
- public const int FontFamily_fontProviderAuthority = 0;
-
- // aapt resource value: 3
- public const int FontFamily_fontProviderCerts = 3;
-
- // aapt resource value: 4
- public const int FontFamily_fontProviderFetchStrategy = 4;
-
- // aapt resource value: 5
- public const int FontFamily_fontProviderFetchTimeout = 5;
-
- // aapt resource value: 1
- public const int FontFamily_fontProviderPackage = 1;
-
- // aapt resource value: 2
- public const int FontFamily_fontProviderQuery = 2;
+ 2130771973,
+ 2130771974};
+ // aapt resource value: { 0x1010532,0x1010533,0x101053F,0x7F010000,0x7F010007,0x7F010008 }
public static int[] FontFamilyFont = new int[] {
16844082,
16844083,
16844095,
- 2130771974,
+ 2130771968,
2130771975,
2130771976};
@@ -561,15 +545,33 @@ namespace SampleApp.Droid
// aapt resource value: 1
public const int FontFamilyFont_android_fontWeight = 1;
- // aapt resource value: 4
- public const int FontFamilyFont_font = 4;
-
// aapt resource value: 3
- public const int FontFamilyFont_fontStyle = 3;
+ public const int FontFamilyFont_font = 3;
+
+ // aapt resource value: 4
+ public const int FontFamilyFont_fontStyle = 4;
// aapt resource value: 5
public const int FontFamilyFont_fontWeight = 5;
+ // aapt resource value: 0
+ public const int FontFamily_fontProviderAuthority = 0;
+
+ // aapt resource value: 1
+ public const int FontFamily_fontProviderCerts = 1;
+
+ // aapt resource value: 2
+ public const int FontFamily_fontProviderFetchStrategy = 2;
+
+ // aapt resource value: 3
+ public const int FontFamily_fontProviderFetchTimeout = 3;
+
+ // aapt resource value: 4
+ public const int FontFamily_fontProviderPackage = 4;
+
+ // aapt resource value: 5
+ public const int FontFamily_fontProviderQuery = 5;
+
static Styleable()
{
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
diff --git a/src/SampleApp.WinDesktop/MainWindow.xaml.cs b/src/SampleApp.WinDesktop/MainWindow.xaml.cs
index 71e24b9..126ffdb 100644
--- a/src/SampleApp.WinDesktop/MainWindow.xaml.cs
+++ b/src/SampleApp.WinDesktop/MainWindow.xaml.cs
@@ -83,24 +83,21 @@ namespace SampleApp.WinDesktop
((NmeaParser.SerialPortDevice)device).Port.BaudRate);
}
}
- Dictionary> gsvMessages = new Dictionary>();
+ Dictionary gsvMessages = new Dictionary();
private void device_MessageReceived(object sender, NmeaParser.NmeaMessageReceivedEventArgs args)
{
Dispatcher.BeginInvoke((Action) delegate()
{
- messages.Enqueue(args.Message.MessageType + ": " + args.Message.ToString());
+ messages.Enqueue(args.Message.ToString());
if (messages.Count > 100) messages.Dequeue(); //Keep message queue at 100
output.Text = string.Join("\n", messages.ToArray());
output.Select(output.Text.Length - 1, 0); //scroll to bottom
- if(args.Message is NmeaParser.Nmea.Gsv gpgsv)
+ if (args.Message is NmeaParser.Nmea.Gsv gpgsv)
{
- if (args.IsMultipart && args.MessageParts != null)
- {
- gsvMessages[args.Message.MessageType] = args.MessageParts.OfType().ToList();
- satView.GsvMessages = gsvMessages.SelectMany(m=>m.Value);
- }
+ gsvMessages[gpgsv.TalkerId] = gpgsv;
+ satView.GsvMessages = gsvMessages.Values;
}
else if (args.Message is NmeaParser.Nmea.Rmc)
gprmcView.Message = args.Message as NmeaParser.Nmea.Rmc;
@@ -112,19 +109,19 @@ namespace SampleApp.WinDesktop
gpgllView.Message = args.Message as NmeaParser.Nmea.Gll;
else if (args.Message is NmeaParser.Nmea.Garmin.Pgrme)
pgrmeView.Message = args.Message as NmeaParser.Nmea.Garmin.Pgrme;
- else
- {
- var ctrl = MessagePanel.Children.OfType().Where(c => c.Message.MessageType == args.Message.MessageType).FirstOrDefault();
- if(ctrl == null)
- {
- ctrl = new UnknownMessageControl()
- {
- Style = this.Resources["card"] as Style
- };
- MessagePanel.Children.Add(ctrl);
- }
- ctrl.Message = args.Message;
- }
+ else
+ {
+ var ctrl = MessagePanel.Children.OfType().Where(c => c.Message.MessageType == args.Message.MessageType).FirstOrDefault();
+ if (ctrl == null)
+ {
+ ctrl = new UnknownMessageControl()
+ {
+ Style = this.Resources["card"] as Style
+ };
+ MessagePanel.Children.Add(ctrl);
+ }
+ ctrl.Message = args.Message;
+ }
});
}
diff --git a/src/UnitTests/NmeaParser.Tests/DeviceTests.cs b/src/UnitTests/NmeaParser.Tests/DeviceTests.cs
index ae045ea..28be409 100644
--- a/src/UnitTests/NmeaParser.Tests/DeviceTests.cs
+++ b/src/UnitTests/NmeaParser.Tests/DeviceTests.cs
@@ -25,19 +25,15 @@ namespace NmeaParser.Tests
count++;
try
{
- Assert.IsTrue(e.IsMultipart, "IsMultiPart");
- Assert.IsInstanceOfType(e.Message, typeof(NmeaParser.Nmea.Gsv));
+ Assert.IsInstanceOfType(e.Message, typeof(Gsv));
var msg = (NmeaParser.Nmea.Gsv)e.Message;
- if (msg.TotalMessages == msg.MessageNumber)
- {
- Assert.IsNotNull(e.MessageParts);
- Assert.AreEqual(e.MessageParts.Count, 3, "MessageParts.Length");
- tcs.SetResult(true);
- }
- else
- Assert.IsNull(e.MessageParts);
- if (count > 3)
+ Assert.IsTrue(((IMultiSentenceMessage)e.Message).IsComplete);
+ Assert.AreEqual(9, msg.SVsInView);
+ Assert.AreEqual(9, msg.SVs.Count);
+
+ if (count > 1)
Assert.Fail();
+ tcs.SetResult(true);
}
catch(System.Exception ex)
{
@@ -61,40 +57,24 @@ $GLGSV,4,3,14,73,52,022,47,74,62,248,47,72,44,331,42,71,78,111,49*6A
$GAGSV,4,4,14,19,82,349,40,1,44,220,40,4,24,314,38*5F";
NmeaDevice dev = new BufferedStringDevice(message);
TaskCompletionSource tcs = new TaskCompletionSource();
- int count = 0;
- dev.MessageReceived += (s, e) =>
- {
- count++;
- try
- {
- Assert.IsTrue(e.IsMultipart, "IsMultiPart");
- Assert.IsInstanceOfType(e.Message, typeof(NmeaParser.Nmea.Gsv));
- var msg = (NmeaParser.Nmea.Gsv)e.Message;
- if (msg.TotalMessages == msg.MessageNumber)
- {
- Assert.IsNotNull(e.MessageParts);
- Assert.AreEqual(e.MessageParts.Count, 4, "MessageParts.Length");
- Assert.IsInstanceOfType(e.MessageParts[0], typeof(NmeaParser.Nmea.Gsv));
- Assert.IsInstanceOfType(e.MessageParts[1], typeof(NmeaParser.Nmea.Gsv));
- Assert.IsInstanceOfType(e.MessageParts[2], typeof(NmeaParser.Nmea.Gsv));
- Assert.IsInstanceOfType(e.MessageParts[3], typeof(NmeaParser.Nmea.Gsv));
- Assert.AreEqual(Talker.GlobalPositioningSystem, e.MessageParts[0].TalkerId);
- Assert.AreEqual(Talker.GlobalPositioningSystem, e.MessageParts[1].TalkerId);
- Assert.AreEqual(Talker.GlonassReceiver, e.MessageParts[2].TalkerId);
- Assert.AreEqual(Talker.GalileoPositioningSystem, e.MessageParts[3].TalkerId);
-
- tcs.SetResult(true);
- }
- else
- Assert.IsNull(e.MessageParts);
- if (count > 3)
- Assert.Fail();
- }
- catch (System.Exception ex)
- {
- tcs.SetException(ex);
- }
- };
+ dev.MessageReceived += (s, e) =>
+ {
+ try
+ {
+ Assert.IsInstanceOfType(e.Message, typeof(NmeaParser.Nmea.Gsv));
+ Assert.AreEqual(Talker.Multiple, e.Message.TalkerId);
+ var msg = (NmeaParser.Nmea.Gsv)e.Message;
+ Assert.AreEqual(Talker.GlobalPositioningSystem, msg.SVs[0].TalkerId);
+ Assert.AreEqual(Talker.GlobalPositioningSystem, msg.SVs[4].TalkerId);
+ Assert.AreEqual(Talker.GlonassReceiver, msg.SVs[8].TalkerId);
+ Assert.AreEqual(Talker.GalileoPositioningSystem, msg.SVs[12].TalkerId);
+ tcs.SetResult(true);
+ }
+ catch (System.Exception ex)
+ {
+ tcs.SetException(ex);
+ }
+ };
await dev.OpenAsync();
await tcs.Task;
var _ = dev.CloseAsync();
@@ -108,27 +88,16 @@ $GAGSV,4,4,14,19,82,349,40,1,44,220,40,4,24,314,38*5F";
var message = "$GPGSV,3,2,9,00,30,055,48,00,19,281,00,27,19,275,00,12,16,319,00*4D\n$GPGSV,3,2,9,00,30,055,48,00,19,281,00,27,19,275,00,12,16,319,00*4F\n$GPGSV,3,3,9,32,10,037,00,,,,,,,,,,,,*74";
NmeaDevice dev = new BufferedStringDevice(message);
TaskCompletionSource tcs = new TaskCompletionSource();
- int count = 0;
+ bool messageRecieved = false;
dev.MessageReceived += (s, e) =>
{
- count++;
- try
- {
- Assert.IsTrue(e.IsMultipart, "IsMultiPart");
- Assert.IsInstanceOfType(e.Message, typeof(NmeaParser.Nmea.Gsv));
- var msg = e.Message as NmeaParser.Nmea.Gsv;
- Assert.IsNull(e.MessageParts);
- if (count > 6)
- tcs.SetResult(true);
- }
- catch (System.Exception ex)
- {
- tcs.SetException(ex);
- }
+ messageRecieved = true;
};
await dev.OpenAsync();
- await tcs.Task;
+ await Task.Delay(100);
var _ = dev.CloseAsync();
+ if (messageRecieved)
+ Assert.Fail("Event shouldn't be raised for incomplete messages");
}
}
}
diff --git a/src/UnitTests/NmeaParser.Tests/NmeaMessages.cs b/src/UnitTests/NmeaParser.Tests/NmeaMessages.cs
index 5a46943..eafcaeb 100644
--- a/src/UnitTests/NmeaParser.Tests/NmeaMessages.cs
+++ b/src/UnitTests/NmeaParser.Tests/NmeaMessages.cs
@@ -302,8 +302,8 @@ namespace NmeaParser.Tests
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gsv));
Gsv gsv = (Gsv)msg;
- Assert.AreEqual(3, gsv.TotalMessages);
- Assert.AreEqual(3, gsv.MessageNumber);
+ Assert.IsInstanceOfType(msg, typeof(IMultiSentenceMessage));
+ Assert.IsFalse(((IMultiSentenceMessage)msg).IsComplete);
Assert.AreEqual(11, gsv.SVsInView);
Assert.IsNotNull(gsv.SVs);
Assert.AreEqual(3, gsv.SVs.Count);
@@ -336,13 +336,75 @@ namespace NmeaParser.Tests
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gsv));
Gsv gsv = (Gsv)msg;
- Assert.AreEqual(1, gsv.TotalMessages);
- Assert.AreEqual(1, gsv.MessageNumber);
+ Assert.IsTrue(((IMultiSentenceMessage)gsv).IsComplete);
Assert.AreEqual(0, gsv.SVsInView);
Assert.IsNotNull(gsv.SVs);
Assert.AreEqual(0, gsv.SVs.Count);
}
+ [TestMethod]
+ public void TestGpgsv_Multi()
+ {
+ var input1 = "$GPGSV,3,1,9,00,30,055,48,00,19,281,00,27,19,275,00,12,16,319,00*4C";
+ var input2 = "$GPGSV,3,2,9,00,30,055,48,00,19,281,00,27,19,275,00,12,16,319,00*4F";
+ var input3 = "$GPGSV,3,3,9,32,10,037,00,,,,,,,,,,,,*74";
+ var msg1 = NmeaMessage.Parse(input1);
+ Assert.IsFalse(((IMultiSentenceMessage)msg1).IsComplete);
+ var msg2 = NmeaMessage.Parse(input2, msg1 as IMultiSentenceMessage);
+ Assert.IsFalse(((IMultiSentenceMessage)msg2).IsComplete);
+ var msg3 = NmeaMessage.Parse(input3, msg2 as IMultiSentenceMessage);
+ Assert.IsTrue(((IMultiSentenceMessage)msg3).IsComplete);
+ Assert.IsInstanceOfType(msg1, typeof(Gsv));
+ Assert.AreSame(msg1, msg2);
+ Assert.AreSame(msg1, msg3);
+ Gsv gsv = (Gsv)msg1;
+ Assert.AreEqual(9, gsv.SVsInView);
+ Assert.IsNotNull(gsv.SVs);
+ Assert.AreEqual(9, gsv.SVs.Count);
+ }
+
+ [TestMethod]
+ public void TestGpgsv_MultiMissing()
+ {
+ var input1 = "$GPGSV,2,1,9,00,30,055,48,00,19,281,00,27,19,275,00,12,16,319,00*4D";
+ var input2 = "$GPGSV,2,2,8,00,30,055,48,00,19,281,00,27,19,275,00,12,16,319,00*4F"; //Satellite count doesn't match, so append will fail
+ var msg1 = NmeaMessage.Parse(input1);
+ Assert.IsFalse(((IMultiSentenceMessage)msg1).IsComplete);
+ var msg2 = NmeaMessage.Parse(input2, msg1 as IMultiSentenceMessage);
+ Assert.IsFalse(((IMultiSentenceMessage)msg2).IsComplete);
+ Assert.IsInstanceOfType(msg2, typeof(Gsv));
+ Assert.AreNotSame(msg1, msg2);
+ Gsv gsv1 = (Gsv)msg1;
+ Assert.AreEqual(9, gsv1.SVsInView);
+ Assert.IsNotNull(gsv1.SVs);
+ Assert.AreEqual(4, gsv1.SVs.Count);
+ Gsv gsv2 = (Gsv)msg2;
+ Assert.AreEqual(8, gsv2.SVsInView);
+ Assert.IsNotNull(gsv2.SVs);
+ Assert.AreEqual(4, gsv2.SVs.Count);
+ }
+
+
+ [TestMethod]
+ public void TestGpgsv_MultiNotMatching()
+ {
+ var input2 = "$GPGSV,3,2,9,00,30,055,48,00,19,281,00,27,19,275,00,12,16,319,00*4F";
+ var input3 = "$GPGSV,3,3,9,32,10,037,00,,,,,,,,,,,,*74";
+ var msg2 = NmeaMessage.Parse(input2);
+ Assert.IsFalse(((IMultiSentenceMessage)msg2).IsComplete);
+ var msg3 = NmeaMessage.Parse(input3, msg2 as IMultiSentenceMessage);
+ Assert.IsFalse(((IMultiSentenceMessage)msg3).IsComplete);
+ Assert.IsInstanceOfType(msg2, typeof(Gsv));
+ Assert.AreNotSame(msg2, msg3);
+ Gsv gsv2 = (Gsv)msg2;
+ Assert.AreEqual(9, gsv2.SVsInView);
+ Assert.IsNotNull(gsv2.SVs);
+ Assert.AreEqual(4, gsv2.SVs.Count);
+ Gsv gsv3 = (Gsv)msg3;
+ Assert.AreEqual(9, gsv3.SVsInView);
+ Assert.IsNotNull(gsv3.SVs);
+ Assert.AreEqual(1, gsv3.SVs.Count);
+ }
[TestMethod]
[WorkItem(53)]
@@ -352,8 +414,7 @@ namespace NmeaParser.Tests
var msg = NmeaMessage.Parse(msgstr);
Assert.IsInstanceOfType(msg, typeof(Gsv));
Gsv gsv = (Gsv)msg;
- Assert.AreEqual(3, gsv.TotalMessages);
- Assert.AreEqual(1, gsv.MessageNumber);
+ Assert.IsFalse(((IMultiSentenceMessage)gsv).IsComplete);
Assert.AreEqual(12, gsv.SVsInView);
Assert.IsNotNull(gsv.SVs);
Assert.AreEqual(4, gsv.SVs.Count);
@@ -581,16 +642,15 @@ namespace NmeaParser.Tests
string input = "$GPRTE,2,1,c,0,W3IWI,DRIVWY,32CEDR,32-29,32BKLD,32-I95,32-US1,BW-32,BW-198*69";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Rte));
- Rte gsv = (Rte)msg;
- Assert.AreEqual(2, gsv.TotalMessages);
- Assert.AreEqual(1, gsv.MessageNumber);
- Assert.AreEqual(Rte.WaypointListType.CompleteWaypointsList, gsv.ListType);
- Assert.AreEqual("0", gsv.RouteId);
- Assert.AreEqual("0", gsv.RouteId);
- Assert.AreEqual(9, gsv.Waypoints.Count);
- Assert.AreEqual("W3IWI", gsv.Waypoints[0]);
- Assert.AreEqual("32BKLD", gsv.Waypoints[4]);
- Assert.AreEqual("BW-198", gsv.Waypoints[8]);
+ Rte rte = (Rte)msg;
+ Assert.IsFalse(((IMultiSentenceMessage)rte).IsComplete);
+ Assert.AreEqual(Rte.WaypointListType.CompleteWaypointsList, rte.ListType);
+ Assert.AreEqual("0", rte.RouteId);
+ Assert.AreEqual("0", rte.RouteId);
+ Assert.AreEqual(9, rte.Waypoints.Count);
+ Assert.AreEqual("W3IWI", rte.Waypoints[0]);
+ Assert.AreEqual("32BKLD", rte.Waypoints[4]);
+ Assert.AreEqual("BW-198", rte.Waypoints[8]);
}
[TestMethod]