/// <summary>
/// Opens the com port and configures it with the required settings
/// </summary>
/// <returns>false if the port could not be opened</returns>
public bool Open()
{
var portDcb = new DCB();
var commTimeouts = new COMMTIMEOUTS();
var wo = new OVERLAPPED();
if (_online) return false;
_hPort = Win32Com.CreateFile(PortName, Win32Com.GENERIC_READ | Win32Com.GENERIC_WRITE, 0, IntPtr.Zero,
Win32Com.OPEN_EXISTING, Win32Com.FILE_FLAG_OVERLAPPED, IntPtr.Zero);
if (_hPort == (IntPtr)Win32Com.INVALID_HANDLE_VALUE)
{
if (Marshal.GetLastWin32Error() == Win32Com.ERROR_ACCESS_DENIED)
{
return false;
}
throw new CommPortException("Port Open Failure");
}
_online = true;
commTimeouts.ReadIntervalTimeout = 0;
commTimeouts.ReadTotalTimeoutConstant = 0;
commTimeouts.ReadTotalTimeoutMultiplier = 0;
commTimeouts.WriteTotalTimeoutConstant = SendTimeoutConstant;
commTimeouts.WriteTotalTimeoutMultiplier = SendTimeoutMultiplier;
portDcb.Init(((Parity == Parity.Odd) || (Parity == Parity.Even)), TxFlowCts, TxFlowDsr,
(int)UseDtr, RxGateDsr, !TxWhenRxXoff, TxFlowX, RxFlowX, (int)UseRts);
portDcb.BaudRate = BaudRate;
portDcb.ByteSize = (byte)DataBits;
portDcb.Parity = (byte)Parity;
portDcb.StopBits = (byte)StopBits;
portDcb.XoffChar = (byte)XoffChar;
portDcb.XonChar = (byte)XonChar;
portDcb.XoffLim = (short)RxHighWater;
portDcb.XonLim = (short)RxLowWater;
if ((RxQueue != 0) || (TxQueue != 0))
if (!Win32Com.SetupComm(_hPort, (uint)RxQueue, (uint)TxQueue)) ThrowException("Bad queue settings");
if (!Win32Com.SetCommState(_hPort, ref portDcb)) ThrowException("Bad com settings");
if (!Win32Com.SetCommTimeouts(_hPort, ref commTimeouts)) ThrowException("Bad timeout settings");
_stateBrk = 0;
if (UseDtr == HsOutput.None) _stateDtr = 0;
if (UseDtr == HsOutput.Online) _stateDtr = 1;
if (UseRts == HsOutput.None) _stateRts = 0;
if (UseRts == HsOutput.Online) _stateRts = 1;
_checkSends = CheckAllSends;
wo.Offset = 0;
wo.OffsetHigh = 0;
wo.hEvent = _checkSends ? _writeEvent.Handle : IntPtr.Zero;
_ptrUwo = Marshal.AllocHGlobal(Marshal.SizeOf(wo));
Marshal.StructureToPtr(wo, _ptrUwo, true);
_writeCount = 0;
_rxException = null;
_rxExceptionReported = false;
_rxThread = new Thread(ReceiveThread)
{
Name = "CommBaseRx",
Priority = ThreadPriority.AboveNormal
};
_rxThread.Start();
Thread.Sleep(1); //Give rx thread time to start. By documentation, 0 should work, but it does not!
_auto = false;
if (AfterOpen())
{
_auto = AutoReopen;
return true;
}
Close();
return false;
}