Merge branch 'nefarius/bugfix/refactoring'

This commit is contained in:
2022-10-03 19:20:37 +02:00
10 changed files with 808 additions and 1047 deletions

View File

@ -1,4 +1,4 @@
CreateFile
CreateFile
GetHandleInformation
SetCommState
SetCommTimeouts

View File

@ -1,149 +1,151 @@
using System.Text;
using Nefarius.Peripherals.SerialPort.Win32PInvoke;
namespace Nefarius.Peripherals.SerialPort;
/// <summary>
/// Represents the current condition of the port queues.
/// </summary>
public readonly struct QueueStatus
namespace Nefarius.Peripherals.SerialPort
{
private const uint fCtsHold = 0x1;
private const uint fDsrHold = 0x2;
private const uint fRlsdHold = 0x4;
private const uint fXoffHold = 0x8;
private const uint fXoffSent = 0x10;
internal const uint fEof = 0x20;
private const uint fTxim = 0x40;
private readonly uint _status;
private readonly uint _inQueue;
private readonly uint _outQueue;
private readonly uint _inQueueSize;
private readonly uint _outQueueSize;
internal QueueStatus(uint stat, uint inQ, uint outQ, uint inQs, uint outQs)
/// <summary>
/// Represents the current condition of the port queues.
/// </summary>
public struct QueueStatus
{
_status = stat;
_inQueue = inQ;
_outQueue = outQ;
_inQueueSize = inQs;
_outQueueSize = outQs;
}
private readonly uint _status;
private readonly uint _inQueue;
private readonly uint _outQueue;
private readonly uint _inQueueSize;
private readonly uint _outQueueSize;
/// <summary>
/// Output is blocked by CTS handshaking.
/// </summary>
public bool CtsHold => (_status & fCtsHold) != 0;
/// <summary>
/// Output is blocked by DRS handshaking.
/// </summary>
public bool DsrHold => (_status & fDsrHold) != 0;
/// <summary>
/// Output is blocked by RLSD handshaking.
/// </summary>
public bool RlsdHold => (_status & fRlsdHold) != 0;
/// <summary>
/// Output is blocked because software handshaking is enabled and XOFF was received.
/// </summary>
public bool XoffHold => (_status & fXoffHold) != 0;
/// <summary>
/// Output was blocked because XOFF was sent and this station is not yet ready to receive.
/// </summary>
public bool XoffSent => (_status & fXoffSent) != 0;
/// <summary>
/// There is a character waiting for transmission in the immediate buffer.
/// </summary>
public bool ImmediateWaiting => (_status & fTxim) != 0;
/// <summary>
/// Number of bytes waiting in the input queue.
/// </summary>
public long InQueue => _inQueue;
/// <summary>
/// Number of bytes waiting for transmission.
/// </summary>
public long OutQueue => _outQueue;
/// <summary>
/// Total size of input queue (0 means information unavailable)
/// </summary>
public long InQueueSize => _inQueueSize;
/// <summary>
/// Total size of output queue (0 means information unavailable)
/// </summary>
public long OutQueueSize => _outQueueSize;
public override string ToString()
{
var m = new StringBuilder("The reception queue is ", 60);
if (_inQueueSize == 0)
m.Append("of unknown size and ");
else
m.Append(_inQueueSize + " bytes long and ");
if (_inQueue == 0)
internal QueueStatus(uint stat, uint inQ, uint outQ, uint inQs, uint outQs)
{
m.Append("is empty.");
}
else if (_inQueue == 1)
{
m.Append("contains 1 byte.");
}
else
{
m.Append("contains ");
m.Append(_inQueue.ToString());
m.Append(" bytes.");
_status = stat;
_inQueue = inQ;
_outQueue = outQ;
_inQueueSize = inQs;
_outQueueSize = outQs;
}
m.Append(" The transmission queue is ");
if (_outQueueSize == 0)
m.Append("of unknown size and ");
else
m.Append(_outQueueSize + " bytes long and ");
if (_outQueue == 0)
{
m.Append("is empty");
}
else if (_outQueue == 1)
{
m.Append("contains 1 byte. It is ");
}
else
{
m.Append("contains ");
m.Append(_outQueue.ToString());
m.Append(" bytes. It is ");
}
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;
if (_outQueue > 0)
/// <summary>
/// Output is blocked by CTS handshaking.
/// </summary>
public bool CtsHold => (_status & fCtsHold) != 0;
/// <summary>
/// Output is blocked by DRS handshaking.
/// </summary>
public bool DsrHold => (_status & fDsrHold) != 0;
/// <summary>
/// Output is blocked by RLSD handshaking.
/// </summary>
public bool RlsdHold => (_status & fRlsdHold) != 0;
/// <summary>
/// Output is blocked because software handshaking is enabled and XOFF was received.
/// </summary>
public bool XoffHold => (_status & fXoffHold) != 0;
/// <summary>
/// Output was blocked because XOFF was sent and this station is not yet ready to receive.
/// </summary>
public bool XoffSent => (_status & fXoffSent) != 0;
/// <summary>
/// There is a character waiting for transmission in the immediate buffer.
/// </summary>
public bool ImmediateWaiting => (_status & fTxim) != 0;
/// <summary>
/// Number of bytes waiting in the input queue.
/// </summary>
public long InQueue => _inQueue;
/// <summary>
/// Number of bytes waiting for transmission.
/// </summary>
public long OutQueue => _outQueue;
/// <summary>
/// Total size of input queue (0 means information unavailable)
/// </summary>
public long InQueueSize => _inQueueSize;
/// <summary>
/// Total size of output queue (0 means information unavailable)
/// </summary>
public long OutQueueSize => _outQueueSize;
public override string ToString()
{
if (CtsHold || DsrHold || RlsdHold || XoffHold || XoffSent)
var m = new StringBuilder("The reception queue is ", 60);
if (_inQueueSize == 0)
m.Append("of unknown size and ");
else
m.Append(_inQueueSize + " bytes long and ");
if (_inQueue == 0)
{
m.Append("holding on");
if (CtsHold) m.Append(" CTS");
if (DsrHold) m.Append(" DSR");
if (RlsdHold) m.Append(" RLSD");
if (XoffHold) m.Append(" Rx XOff");
if (XoffSent) m.Append(" Tx XOff");
m.Append("is empty.");
}
else if (_inQueue == 1)
{
m.Append("contains 1 byte.");
}
else
{
m.Append("pumping data");
m.Append("contains ");
m.Append(_inQueue.ToString());
m.Append(" bytes.");
}
}
m.Append(". The immediate buffer is ");
if (ImmediateWaiting)
m.Append("full.");
else
m.Append("empty.");
return m.ToString();
m.Append(" The transmission queue is ");
if (_outQueueSize == 0)
m.Append("of unknown size and ");
else
m.Append(_outQueueSize + " bytes long and ");
if (_outQueue == 0)
{
m.Append("is empty");
}
else if (_outQueue == 1)
{
m.Append("contains 1 byte. It is ");
}
else
{
m.Append("contains ");
m.Append(_outQueue.ToString());
m.Append(" bytes. It is ");
}
if (_outQueue > 0)
{
if (CtsHold || DsrHold || RlsdHold || XoffHold || XoffSent)
{
m.Append("holding on");
if (CtsHold) m.Append(" CTS");
if (DsrHold) m.Append(" DSR");
if (RlsdHold) m.Append(" RLSD");
if (XoffHold) m.Append(" Rx XOff");
if (XoffSent) m.Append(" Tx XOff");
}
else
{
m.Append("pumping data");
}
}
m.Append(". The immediate buffer is ");
if (ImmediateWaiting)
m.Append("full.");
else
m.Append("empty.");
return m.ToString();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@ namespace Nefarius.Peripherals.SerialPort;
internal static class DCBExtensions
{
public static void Init(this DCB dcb, bool parity, bool outCts, bool outDsr, int dtr, bool inDsr, bool txc,
public static void Init(this ref DCB dcb, bool parity, bool outCts, bool outDsr, int dtr, bool inDsr, bool txc,
bool xOut,
bool xIn, int rts)
{

View File

@ -0,0 +1,91 @@
using System;
using System.Runtime.InteropServices;
namespace Nefarius.Peripherals.SerialPort.Win32PInvoke
{
internal class Win32Com
{
[DllImport("kernel32.dll")]
internal static extern Boolean GetHandleInformation(IntPtr hObject, out UInt32 lpdwFlags);
[DllImport("kernel32.dll")]
internal static extern Boolean SetCommMask(IntPtr hFile, UInt32 dwEvtMask);
// Constants for dwEvtMask:
internal const UInt32 EV_RXCHAR = 0x0001;
internal const UInt32 EV_RXFLAG = 0x0002;
internal const UInt32 EV_TXEMPTY = 0x0004;
internal const UInt32 EV_CTS = 0x0008;
internal const UInt32 EV_DSR = 0x0010;
internal const UInt32 EV_RLSD = 0x0020;
internal const UInt32 EV_BREAK = 0x0040;
internal const UInt32 EV_ERR = 0x0080;
internal const UInt32 EV_RING = 0x0100;
internal const UInt32 EV_PERR = 0x0200;
internal const UInt32 EV_RX80FULL = 0x0400;
internal const UInt32 EV_EVENT1 = 0x0800;
internal const UInt32 EV_EVENT2 = 0x1000;
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern Boolean WaitCommEvent(IntPtr hFile, IntPtr lpEvtMask, IntPtr lpOverlapped);
[DllImport("kernel32.dll")]
internal static extern Boolean CancelIo(IntPtr hFile);
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern Boolean ReadFile(IntPtr hFile, [Out] Byte[] lpBuffer, UInt32 nNumberOfBytesToRead,
out UInt32 nNumberOfBytesRead, IntPtr lpOverlapped);
[DllImport("kernel32.dll")]
internal static extern Boolean TransmitCommChar(IntPtr hFile, Byte cChar);
/// <summary>
/// Control port functions.
/// </summary>
[DllImport("kernel32.dll")]
internal static extern Boolean EscapeCommFunction(IntPtr hFile, UInt32 dwFunc);
// Constants for dwFunc:
internal const UInt32 SETXOFF = 1;
internal const UInt32 SETXON = 2;
internal const UInt32 SETRTS = 3;
internal const UInt32 CLRRTS = 4;
internal const UInt32 SETDTR = 5;
internal const UInt32 CLRDTR = 6;
internal const UInt32 RESETDEV = 7;
internal const UInt32 SETBREAK = 8;
internal const UInt32 CLRBREAK = 9;
[DllImport("kernel32.dll")]
internal static extern Boolean GetCommModemStatus(IntPtr hFile, out UInt32 lpModemStat);
// Constants for lpModemStat:
internal const UInt32 MS_CTS_ON = 0x0010;
internal const UInt32 MS_DSR_ON = 0x0020;
internal const UInt32 MS_RING_ON = 0x0040;
internal const UInt32 MS_RLSD_ON = 0x0080;
/// <summary>
/// Status Functions.
/// </summary>
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern Boolean GetOverlappedResult(IntPtr hFile, IntPtr lpOverlapped,
out UInt32 nNumberOfBytesTransferred, Boolean bWait);
//Constants for lpErrors:
internal const UInt32 CE_RXOVER = 0x0001;
internal const UInt32 CE_OVERRUN = 0x0002;
internal const UInt32 CE_RXPARITY = 0x0004;
internal const UInt32 CE_FRAME = 0x0008;
internal const UInt32 CE_BREAK = 0x0010;
internal const UInt32 CE_TXFULL = 0x0100;
internal const UInt32 CE_PTO = 0x0200;
internal const UInt32 CE_IOE = 0x0400;
internal const UInt32 CE_DNS = 0x0800;
internal const UInt32 CE_OOP = 0x1000;
internal const UInt32 CE_MODE = 0x8000;
}
}