mirror of
https://github.com/dotMorten/NmeaParser.git
synced 2026-02-04 06:44:27 +01:00
Simplified listening to multi part messages
This commit is contained in:
parent
b2e4d7c2a6
commit
2fba15f6d9
|
|
@ -4,8 +4,8 @@ using System.Text;
|
|||
|
||||
namespace NmeaParser
|
||||
{
|
||||
interface IMultiPartMessage<T> : IEnumerable<T>
|
||||
{
|
||||
interface IMultiPartMessage : System.Collections.IEnumerable
|
||||
{
|
||||
/// <summary>
|
||||
/// Total number of messages of this type in this cycle
|
||||
/// </summary>
|
||||
|
|
@ -16,4 +16,7 @@ namespace NmeaParser
|
|||
/// </summary>
|
||||
int MessageNumber { get; }
|
||||
}
|
||||
interface IMultiPartMessage<T> : IMultiPartMessage, IEnumerable<T>
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ namespace NmeaParser
|
|||
tcs = new System.Threading.CancellationTokenSource();
|
||||
m_stream = await OpenStreamAsync();
|
||||
StartParser();
|
||||
MultiPartMessageCache.Clear();
|
||||
}
|
||||
|
||||
private void StartParser()
|
||||
|
|
@ -82,6 +83,7 @@ namespace NmeaParser
|
|||
}
|
||||
await closeTask.Task;
|
||||
await CloseStreamAsync(m_stream);
|
||||
MultiPartMessageCache.Clear();
|
||||
m_stream = null;
|
||||
}
|
||||
protected abstract Task CloseStreamAsync(Stream stream);
|
||||
|
|
@ -98,7 +100,7 @@ namespace NmeaParser
|
|||
if (lineEnd > -1)
|
||||
{
|
||||
line = message.Substring(0, lineEnd).Trim();
|
||||
message = message.Substring(lineEnd);
|
||||
message = message.Substring(lineEnd + 1);
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(line))
|
||||
|
|
@ -118,10 +120,46 @@ namespace NmeaParser
|
|||
|
||||
private void OnMessageReceived(Nmea.NmeaMessage msg)
|
||||
{
|
||||
var args = new NmeaMessageReceivedEventArgs(msg);
|
||||
if (msg is IMultiPartMessage)
|
||||
{
|
||||
args.IsMultiPart = true;
|
||||
var multi = (IMultiPartMessage)msg;
|
||||
if (MultiPartMessageCache.ContainsKey(msg.MessageType))
|
||||
{
|
||||
var dic = MultiPartMessageCache[msg.MessageType];
|
||||
if (dic.ContainsKey(multi.MessageNumber - 1) && !dic.ContainsKey(multi.MessageNumber))
|
||||
{
|
||||
dic[multi.MessageNumber] = msg;
|
||||
}
|
||||
else //Something is out of order. Clear cache
|
||||
MultiPartMessageCache.Remove(msg.MessageType);
|
||||
}
|
||||
else if (multi.MessageNumber == 1)
|
||||
{
|
||||
MultiPartMessageCache[msg.MessageType] = new Dictionary<int, Nmea.NmeaMessage>(multi.TotalMessages);
|
||||
MultiPartMessageCache[msg.MessageType][1] = msg;
|
||||
}
|
||||
if (MultiPartMessageCache.ContainsKey(msg.MessageType))
|
||||
{
|
||||
var dic = MultiPartMessageCache[msg.MessageType];
|
||||
if (dic.Count == multi.TotalMessages) //We have a full list
|
||||
{
|
||||
MultiPartMessageCache.Remove(msg.MessageType);
|
||||
args.MessageParts = dic.Values.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (MessageReceived != null)
|
||||
MessageReceived(this, new NmeaMessageReceivedEventArgs(msg));
|
||||
{
|
||||
MessageReceived(this, args);
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<string, Dictionary<int, Nmea.NmeaMessage>> MultiPartMessageCache
|
||||
= new Dictionary<string,Dictionary<int,Nmea.NmeaMessage>>();
|
||||
|
||||
public event EventHandler<NmeaMessageReceivedEventArgs> MessageReceived;
|
||||
|
||||
public void Dispose()
|
||||
|
|
@ -147,10 +185,9 @@ namespace NmeaParser
|
|||
{
|
||||
internal NmeaMessageReceivedEventArgs(Nmea.NmeaMessage message) {
|
||||
Message = message;
|
||||
MessageList = new[] { message };
|
||||
}
|
||||
public Nmea.NmeaMessage Message { get; private set; }
|
||||
public bool IsMultiPart { get; internal set; }
|
||||
public Nmea.NmeaMessage[] MessageList { get; internal set; }
|
||||
public Nmea.NmeaMessage[] MessageParts { get; internal set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,25 +28,18 @@ namespace SampleApp.WinDesktop
|
|||
var _ = device.OpenAsync();
|
||||
}
|
||||
|
||||
Dictionary<int, NmeaParser.Nmea.Gps.Gpgsv> gpgsvList = new Dictionary<int,NmeaParser.Nmea.Gps.Gpgsv>();
|
||||
private void device_MessageReceived(object sender, NmeaParser.NmeaMessageReceivedEventArgs args)
|
||||
{
|
||||
Dispatcher.BeginInvoke((Action) delegate()
|
||||
{
|
||||
output.Text += args.Message.MessageType + ": " + args.ToString() + '\n';
|
||||
output.Text += args.Message.MessageType + ": " + args.Message.ToString() + '\n';
|
||||
output.Select(output.Text.Length - 1, 0); //scroll to bottom
|
||||
|
||||
//Merge all gpgsv satellite messages
|
||||
if(args.Message is NmeaParser.Nmea.Gps.Gpgsv)
|
||||
{
|
||||
var gpgsv = (NmeaParser.Nmea.Gps.Gpgsv)args.Message;
|
||||
if(gpgsv.MessageNumber == 1)
|
||||
{
|
||||
gpgsvList = new Dictionary<int,NmeaParser.Nmea.Gps.Gpgsv>(); //first one. Replace list
|
||||
}
|
||||
gpgsvList[gpgsv.MessageNumber] = gpgsv;
|
||||
if(gpgsv.MessageNumber == gpgsv.TotalMessages)
|
||||
satView.GpgsvMessages = gpgsvList.Values;
|
||||
if(args.IsMultiPart && args.MessageParts != null)
|
||||
satView.GpgsvMessages = args.MessageParts.OfType<NmeaParser.Nmea.Gps.Gpgsv>();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue