diff --git a/src/NmeaParser/NmeaDevice.cs b/src/NmeaParser/NmeaDevice.cs
index 3794903..2a2c076 100644
--- a/src/NmeaParser/NmeaDevice.cs
+++ b/src/NmeaParser/NmeaDevice.cs
@@ -80,6 +80,7 @@ namespace NmeaParser
readCount = await ReadAsync(buffer, 0, 1024, token).ConfigureAwait(false);
failcounter = 0;
}
+ catch (TaskCanceledException) { }
catch (TimeoutException t)
{
OnDisconnecting(t);
diff --git a/src/NmeaParser/SerialPortDevice.Desktop.cs b/src/NmeaParser/SerialPortDevice.Desktop.cs
index ea855ba..6940993 100644
--- a/src/NmeaParser/SerialPortDevice.Desktop.cs
+++ b/src/NmeaParser/SerialPortDevice.Desktop.cs
@@ -19,9 +19,11 @@ using System.Linq;
using System.Text;
using System.IO;
using System.Threading.Tasks;
+using System.IO.Ports;
+using System.Threading;
namespace NmeaParser
-{
+{
///
/// A Serial Port NMEA device
///
@@ -42,6 +44,9 @@ namespace NmeaParser
/// }
///
///
+#if WINDOWS && NET6_0_OR_GREATER
+ [Obsolete("Use WinRTSerialDevice type instead, as the underlying SerialPort implementation comes with a range of issues")]
+#endif
public class SerialPortDevice : NmeaDevice
{
///
@@ -69,6 +74,26 @@ namespace NmeaParser
return Task.FromResult(Port.BaseStream);
}
+ //private class SerialPortStreamWrapper : Stream
+ //{
+ // private SerialPort port;
+ // public SerialPortStreamWrapper(SerialPort port)
+ // {
+ // this.port = port;
+ // }
+
+ // public override int Read(byte[] buffer, int offset, int count) => port.Read(buffer, offset, count);
+
+ // public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
+ // {
+
+ // return base.ReadAsync(buffer, offset, count, cancellationToken);
+ // }
+ // public override int ReadTimeout { get => port.ReadTimeout ; set => port.ReadTimeout = value; }
+
+ // public override int WriteTimeout { get => port.WriteTimeout; set => port.WriteTimeout = value; }
+ //}
+
///
protected override Task CloseStreamAsync(System.IO.Stream stream)
{
diff --git a/src/NmeaParser/SerialPortDevice.UWP.cs b/src/NmeaParser/SerialPortDevice.UWP.cs
index 8fe2131..a3b930d 100644
--- a/src/NmeaParser/SerialPortDevice.UWP.cs
+++ b/src/NmeaParser/SerialPortDevice.UWP.cs
@@ -60,6 +60,7 @@ namespace NmeaParser
/// }
///
///
+ [Obsolete("Use WinRTSerialDevice type instead")]
public class SerialPortDevice : NmeaDevice
{
private SerialDevice m_port;
diff --git a/src/NmeaParser/WinRTSerialDevice.cs b/src/NmeaParser/WinRTSerialDevice.cs
new file mode 100644
index 0000000..70aca0d
--- /dev/null
+++ b/src/NmeaParser/WinRTSerialDevice.cs
@@ -0,0 +1,149 @@
+
+// *******************************************************************************
+// * 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.
+// ******************************************************************************
+
+#if WINDOWS_UWP || NET6_0_OR_GREATER && WINDOWS
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.IO;
+using System.Threading.Tasks;
+using Windows.Devices.SerialCommunication;
+using System.Runtime.InteropServices.WindowsRuntime;
+
+namespace NmeaParser
+{
+ ///
+ /// A Serial Port NMEA device using Windows' WinRT APIs.
+ ///
+ ///
+ ///
+ /// To use the NMEA Parser against a serial device in a Windows 10 Universal app, ensure the serial device capability is enabled by opening package.appxmanifest in a text editor, and add the following to the <Capabilities> section:
+ ///
+ ///
+ /// <DeviceCapability Name="serialcommunication">
+ /// <Device Id="any">
+ /// <Function Type="name:serialPort" />
+ /// </Device>
+ /// </DeviceCapability>
+ ///
+ ///
+ /// var selector = SerialDevice.GetDeviceSelector("COM3"); //Get the serial port on port '3'
+ /// var devices = await DeviceInformation.FindAllAsync(selector);
+ /// if(devices.Any()) //if the device is found
+ /// {
+ /// var deviceInfo = devices.First();
+ /// var serialDevice = await SerialDevice.FromIdAsync(deviceInfo.Id);
+ /// //Set up serial device according to device specifications:
+ /// //This might differ from device to device
+ /// serialDevice.BaudRate = 4800;
+ /// serialDevice.DataBits = 8;
+ /// serialDevice.Parity = SerialParity.None;
+ /// var device = new NmeaParser.SerialPortDevice(serialDevice);
+ /// device.MessageReceived += device_NmeaMessageReceived;
+ /// }
+ /// ...
+ /// private void device_NmeaMessageReceived(NmeaParser.NmeaDevice sender, NmeaMessageReceivedEventArgs args)
+ /// {
+ /// // called when a message is received
+ /// }
+ ///
+ ///
+ public class WinRTSerialDevice : NmeaDevice
+ {
+ private SerialDevice m_port;
+
+ ///
+ /// Gets a list of serial devices available.
+ ///
+ /// A set of serial devices available.
+ public static async Task> GetSerialDevicesAsync()
+ {
+ List services = new List();
+ if(Windows.Foundation.Metadata.ApiInformation.IsMethodPresent("Windows.Devices.Enumeration.DeviceInformation", "FindAllAsync")) // Ensure we are on an OS where these WinRT APIs are supported
+ {
+
+ if (Windows.Foundation.Metadata.ApiInformation.IsMethodPresent("Windows.Devices.SerialCommunication.SerialDevice", "GetDeviceSelector"))
+ {
+ var devices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(SerialDevice.GetDeviceSelector());
+ foreach (var d in devices)
+ services.Add(await SerialDevice.FromIdAsync(d.Id));
+ }
+ }
+ return services;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The serial port.
+ /// port
+ public WinRTSerialDevice(SerialDevice device)
+ {
+ if (device == null)
+ throw new ArgumentNullException("device");
+ m_port = device;
+ }
+
+ ///
+ /// Gets the active serial port.
+ ///
+ public SerialDevice SerialDevice
+ {
+ get
+ {
+ return m_port;
+ }
+ }
+
+ ///
+ protected override Task OpenStreamAsync()
+ {
+ return Task.FromResult(m_port.InputStream.AsStreamForRead(0));
+ }
+
+ ///
+ protected override Task CloseStreamAsync(System.IO.Stream stream)
+ {
+ return Task.CompletedTask;
+ }
+
+ ///
+ /// Writes data to the serial port (useful for RTCM/dGPS scenarios)
+ ///
+ /// The byte array that contains the data to write to the port.
+ /// The zero-based byte offset in the buffer parameter at which to begin copying
+ /// bytes to the port.
+ /// The number of bytes to write.
+ [Obsolete("Use WriteAsync")]
+ public void Write(byte[] buffer, int offset, int count)
+ {
+ m_port.OutputStream.AsStreamForWrite().Write(buffer, offset, count);
+ }
+
+ ///
+ public override bool CanWrite => true;
+
+ ///
+ public override Task WriteAsync(byte[] buffer, int offset, int length)
+ {
+ if (m_port == null)
+ throw new InvalidOperationException("Device not open");
+
+ return m_port.OutputStream.WriteAsync(buffer.AsBuffer(offset, length)).AsTask();
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/SampleApp.WinDesktop/MainWindow.xaml.cs b/src/SampleApp.WinDesktop/MainWindow.xaml.cs
index 639674f..123f97c 100644
--- a/src/SampleApp.WinDesktop/MainWindow.xaml.cs
+++ b/src/SampleApp.WinDesktop/MainWindow.xaml.cs
@@ -1,4 +1,5 @@
-using NmeaParser.Gnss;
+using NmeaParser;
+using NmeaParser.Gnss;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -6,6 +7,8 @@ using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
+using Windows.Devices.Enumeration;
+using Windows.Devices.SerialCommunication;
namespace SampleApp.WinDesktop
{
@@ -28,22 +31,32 @@ namespace SampleApp.WinDesktop
public MainWindow()
{
InitializeComponent();
-
- //Get list of serial ports for device tab
- var availableSerialPorts = System.IO.Ports.SerialPort.GetPortNames().OrderBy(s => s);
- serialPorts.ItemsSource = availableSerialPorts;
- serialPorts.SelectedIndex = 0;
- // Use serial portName:
- //var comPort = availableSerialPorts.First();
- //var portName = new System.IO.Ports.SerialPort(comPort, 4800);
- //var device = new NmeaParser.SerialPortDevice(portName);
-
//Use a log file for playing back logged data
var device = new NmeaParser.NmeaFileDevice("NmeaSampleData.txt") { EmulatedBaudRate = 9600, BurstRate = TimeSpan.FromSeconds(1d) };
_ = StartDevice(device);
+ LoadSerialDevices();
LoadBluetoothDevices();
+ }
+ //Get list of serial ports for device tab
+ private async void LoadSerialDevices()
+ {
+ var deviceList = new List();
+ var devices = await WinRTSerialDevice.GetSerialDevicesAsync();
+ foreach (var item in devices)
+ {
+ deviceList.Add(new DeviceInfo()
+ {
+ DisplayName = $"{item.PortName}",
+ CreateMethod = () =>
+ {
+ return Task.FromResult(new WinRTSerialDevice(item));
+ }
+ });
+ }
+ serialPorts.ItemsSource = deviceList;
+ serialPorts.SelectedIndex = 0;
}
public class DeviceInfo
{
@@ -206,9 +219,10 @@ namespace SampleApp.WinDesktop
{
try
{
- var portName = serialPorts.Text as string;
- var baudRate = int.Parse(baudRates.Text);
- var device = new NmeaParser.SerialPortDevice(new System.IO.Ports.SerialPort(portName, baudRate));
+ var portName = serialPorts.SelectedItem as DeviceInfo;
+ var baudRate = uint.Parse(baudRates.Text);
+ var device = await portName.CreateMethod() as WinRTSerialDevice;
+ device.SerialDevice.BaudRate = baudRate;
try
{
await StartDevice(device);