diff --git a/Nefarius.Peripherals.SerialPort/QueueStatus.cs b/Nefarius.Peripherals.SerialPort/QueueStatus.cs index 69bf8de..63469fd 100644 --- a/Nefarius.Peripherals.SerialPort/QueueStatus.cs +++ b/Nefarius.Peripherals.SerialPort/QueueStatus.cs @@ -23,35 +23,43 @@ namespace Nefarius.Peripherals.SerialPort _outQueueSize = outQs; } + internal const uint fCtsHold = 0x1; + internal const uint fDsrHold = 0x2; + internal const uint fRlsdHold = 0x4; + internal const uint fXoffHold = 0x8; + internal const uint fXoffSent = 0x10; + internal const uint fEof = 0x20; + internal const uint fTxim = 0x40; + /// /// Output is blocked by CTS handshaking. /// - public bool CtsHold => (_status & COMSTAT.fCtsHold) != 0; + public bool CtsHold => (_status & fCtsHold) != 0; /// /// Output is blocked by DRS handshaking. /// - public bool DsrHold => (_status & COMSTAT.fDsrHold) != 0; + public bool DsrHold => (_status & fDsrHold) != 0; /// /// Output is blocked by RLSD handshaking. /// - public bool RlsdHold => (_status & COMSTAT.fRlsdHold) != 0; + public bool RlsdHold => (_status & fRlsdHold) != 0; /// /// Output is blocked because software handshaking is enabled and XOFF was received. /// - public bool XoffHold => (_status & COMSTAT.fXoffHold) != 0; + public bool XoffHold => (_status & fXoffHold) != 0; /// /// Output was blocked because XOFF was sent and this station is not yet ready to receive. /// - public bool XoffSent => (_status & COMSTAT.fXoffSent) != 0; + public bool XoffSent => (_status & fXoffSent) != 0; /// /// There is a character waiting for transmission in the immediate buffer. /// - public bool ImmediateWaiting => (_status & COMSTAT.fTxim) != 0; + public bool ImmediateWaiting => (_status & fTxim) != 0; /// /// Number of bytes waiting in the input queue. diff --git a/Nefarius.Peripherals.SerialPort/SerialPort.cs b/Nefarius.Peripherals.SerialPort/SerialPort.cs index 8d58f3f..dd22fb5 100644 --- a/Nefarius.Peripherals.SerialPort/SerialPort.cs +++ b/Nefarius.Peripherals.SerialPort/SerialPort.cs @@ -9,7 +9,6 @@ using Windows.Win32.Storage.FileSystem; using Microsoft.Win32.SafeHandles; using Nefarius.Peripherals.SerialPort.Win32PInvoke; using COMMPROP = Nefarius.Peripherals.SerialPort.Win32PInvoke.COMMPROP; -using COMSTAT = Nefarius.Peripherals.SerialPort.Win32PInvoke.COMSTAT; namespace Nefarius.Peripherals.SerialPort; @@ -298,16 +297,20 @@ public class SerialPort : IDisposable /// Get the status of the queues /// /// Queue status object - protected QueueStatus GetQueueStatus() + protected unsafe QueueStatus GetQueueStatus() { COMSTAT cs; COMMPROP cp; - uint er; + CLEAR_COMM_ERROR_FLAGS er; CheckOnline(); - if (!Win32Com.ClearCommError(_hPort.DangerousGetHandle(), out er, out cs)) ThrowException("Unexpected failure"); - if (!Win32Com.GetCommProperties(_hPort.DangerousGetHandle(), out cp)) ThrowException("Unexpected failure"); - return new QueueStatus(cs.Flags, cs.cbInQue, cs.cbOutQue, cp.dwCurrentRxQueue, cp.dwCurrentTxQueue); + if (!PInvoke.ClearCommError(_hPort, &er, &cs)) + ThrowException("Unexpected failure"); + + if (!Win32Com.GetCommProperties(_hPort.DangerousGetHandle(), out cp)) + ThrowException("Unexpected failure"); + + return new QueueStatus(cs._bitfield, cs.cbInQue, cs.cbOutQue, cp.dwCurrentRxQueue, cp.dwCurrentTxQueue); } /// @@ -378,7 +381,7 @@ public class SerialPort : IDisposable { } - private void ReceiveThread() + private unsafe void ReceiveThread() { var buf = new byte[1]; @@ -413,16 +416,16 @@ public class SerialPort : IDisposable eventMask = (uint)Marshal.ReadInt32(uMask); if ((eventMask & Win32Com.EV_ERR) != 0) { - uint errs; - if (Win32Com.ClearCommError(_hPort.DangerousGetHandle(), out errs, IntPtr.Zero)) + CLEAR_COMM_ERROR_FLAGS errs; + if (PInvoke.ClearCommError(_hPort, &errs, null)) { var s = new StringBuilder("UART Error: ", 40); - if ((errs & Win32Com.CE_FRAME) != 0) s = s.Append("Framing,"); - if ((errs & Win32Com.CE_IOE) != 0) s = s.Append("IO,"); - if ((errs & Win32Com.CE_OVERRUN) != 0) s = s.Append("Overrun,"); - if ((errs & Win32Com.CE_RXOVER) != 0) s = s.Append("Receive Overflow,"); - if ((errs & Win32Com.CE_RXPARITY) != 0) s = s.Append("Parity,"); - if ((errs & Win32Com.CE_TXFULL) != 0) s = s.Append("Transmit Overflow,"); + if (((uint)errs & Win32Com.CE_FRAME) != 0) s = s.Append("Framing,"); + if (((uint)errs & Win32Com.CE_IOE) != 0) s = s.Append("IO,"); + if (((uint)errs & Win32Com.CE_OVERRUN) != 0) s = s.Append("Overrun,"); + if (((uint)errs & Win32Com.CE_RXOVER) != 0) s = s.Append("Receive Overflow,"); + if (((uint)errs & Win32Com.CE_RXPARITY) != 0) s = s.Append("Parity,"); + if (((uint)errs & Win32Com.CE_TXFULL) != 0) s = s.Append("Transmit Overflow,"); s.Length = s.Length - 1; throw new CommPortException(s.ToString()); } diff --git a/Nefarius.Peripherals.SerialPort/Win32PInvoke/COMSTAT.cs b/Nefarius.Peripherals.SerialPort/Win32PInvoke/COMSTAT.cs deleted file mode 100644 index 523182c..0000000 --- a/Nefarius.Peripherals.SerialPort/Win32PInvoke/COMSTAT.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace Nefarius.Peripherals.SerialPort.Win32PInvoke -{ - [StructLayout(LayoutKind.Sequential)] - internal struct COMSTAT - { - internal const uint fCtsHold = 0x1; - internal const uint fDsrHold = 0x2; - internal const uint fRlsdHold = 0x4; - internal const uint fXoffHold = 0x8; - internal const uint fXoffSent = 0x10; - internal const uint fEof = 0x20; - internal const uint fTxim = 0x40; - internal UInt32 Flags; - internal UInt32 cbInQue; - internal UInt32 cbOutQue; - } -} \ No newline at end of file diff --git a/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs b/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs index 58b9e11..3a89c67 100644 --- a/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs +++ b/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs @@ -88,11 +88,6 @@ namespace Nefarius.Peripherals.SerialPort.Win32PInvoke internal static extern Boolean GetOverlappedResult(IntPtr hFile, IntPtr lpOverlapped, out UInt32 nNumberOfBytesTransferred, Boolean bWait); - [DllImport("kernel32.dll")] - internal static extern Boolean ClearCommError(IntPtr hFile, out UInt32 lpErrors, IntPtr lpStat); - [DllImport("kernel32.dll")] - internal static extern Boolean ClearCommError(IntPtr hFile, out UInt32 lpErrors, out COMSTAT cs); - //Constants for lpErrors: internal const UInt32 CE_RXOVER = 0x0001; internal const UInt32 CE_OVERRUN = 0x0002;