public bool Close() { CommErrorFlags flags; if (this.txOverlapped != IntPtr.Zero) { LocalFree(this.txOverlapped); this.txOverlapped = IntPtr.Zero; } if (this.rxOverlapped != IntPtr.Zero) { LocalFree(this.rxOverlapped); this.rxOverlapped = IntPtr.Zero; } if (this.hPort == IntPtr.Zero) { return(false); } int num = 0; Label_0068: flags = 0; CommStat stat = new CommStat(); if (!this.m_CommAPI.ClearCommError(this.hPort, ref flags, stat) || (stat.cbOutQue != 0)) { Thread.Sleep(1); if (num < 3) { num++; Thread.Sleep(10); goto Label_0068; } } this.m_CommAPI.PurgeComm(this.hPort, 0); this.m_CommAPI.CloseHandle(this.hPort); this.m_CommAPI.SetEvent(this.closeEvent); this.isOpen = false; this.hPort = (IntPtr)(-1); return(true); }
private static extern int CEClearCommError(IntPtr hFile, ref CommErrorFlags lpErrors, CommStat lpStat);
internal override bool ClearCommError(IntPtr hPort, ref CommErrorFlags flags, CommStat stat) { return(Convert.ToBoolean(CEClearCommError(hPort, ref flags, stat))); }
private void CommEventThread() { CommEventFlags eventFlags = new CommEventFlags(); byte[] readbuffer = new Byte[rxBufferSize]; int bytesread = 0; AutoResetEvent rxevent = new AutoResetEvent(false); // specify the set of events to be monitored for the port. if (CommAPI.FullFramework) { m_CommAPI.SetCommMask(hPort, CommEventFlags.ALLPC); // set up the overlapped IO OVERLAPPED o = new OVERLAPPED(); rxOverlapped = LocalAlloc(0x40, Marshal.SizeOf(o)); o.Offset = 0; o.OffsetHigh = 0; o.hEvent = rxevent.Handle; Marshal.StructureToPtr(o, rxOverlapped, true); } else { m_CommAPI.SetCommMask(hPort, CommEventFlags.ALLCE); } try { // let Open() know we're started threadStarted.Set(); #region >>>> thread loop <<<< while (hPort != (IntPtr)CommAPI.INVALID_HANDLE_VALUE) { // wait for a Comm event if (!m_CommAPI.WaitCommEvent(hPort, ref eventFlags)) { int e = Marshal.GetLastWin32Error(); if (e == (int)APIErrors.ERROR_IO_PENDING) { // IO pending so just wait and try again rxevent.WaitOne(); Thread.Sleep(0); continue; } if (e == (int)APIErrors.ERROR_INVALID_HANDLE) { // Calling Port.Close() causes hPort to become invalid // Since Thread.Abort() is unsupported in the CF, we must // accept that calling Close will throw an error here. // Close signals the closeEvent, so wait on it // We wait 1 second, though Close should happen much sooner int eventResult = m_CommAPI.WaitForSingleObject(closeEvent, 1000); if (eventResult == (int)APIConstants.WAIT_OBJECT_0) { // the event was set so close was called hPort = (IntPtr)CommAPI.INVALID_HANDLE_VALUE; // reset our ResetEvent for the next call to Open threadStarted.Reset(); if (isOpen) // this should not be the case...if so, throw an exception for the owner { string error = String.Format("Wait Failed: {0}", e); throw new CommPortException(error); } return; } } // WaitCommEvent failed // 995 means an exit was requested (thread killed) if (e == 995) { return; } else { string error = String.Format("Wait Failed: {0}", e); throw new CommPortException(error); } } // Re-specify the set of events to be monitored for the port. if (CommAPI.FullFramework) { m_CommAPI.SetCommMask(hPort, CommEventFlags.ALLPC); } else { m_CommAPI.SetCommMask(hPort, CommEventFlags.ALLCE); } // check the event for errors #region >>>> error checking <<<< if (((uint)eventFlags & (uint)CommEventFlags.ERR) != 0) { CommErrorFlags errorFlags = new CommErrorFlags(); CommStat commStat = new CommStat(); // get the error status if (!m_CommAPI.ClearCommError(hPort, ref errorFlags, commStat)) { // ClearCommError failed! string error = String.Format("ClearCommError Failed: {0}", Marshal.GetLastWin32Error()); throw new CommPortException(error); } if (((uint)errorFlags & (uint)CommErrorFlags.BREAK) != 0) { // BREAK can set an error, so make sure the BREAK bit is set an continue eventFlags |= CommEventFlags.BREAK; } else { // we have an error. Build a meaningful string and throw an exception StringBuilder s = new StringBuilder("UART Error: ", 80); if ((errorFlags & CommErrorFlags.FRAME) != 0) { s = s.Append("Framing,"); } if ((errorFlags & CommErrorFlags.IOE) != 0) { s = s.Append("IO,"); } if ((errorFlags & CommErrorFlags.OVERRUN) != 0) { s = s.Append("Overrun,"); } if ((errorFlags & CommErrorFlags.RXOVER) != 0) { s = s.Append("Receive Overflow,"); } if ((errorFlags & CommErrorFlags.RXPARITY) != 0) { s = s.Append("Parity,"); } if ((errorFlags & CommErrorFlags.TXFULL) != 0) { s = s.Append("Transmit Overflow,"); } // no known bits are set if (s.Length == 12) { s = s.Append("Unknown"); } // raise an error event if (OnError != null) { OnError(s.ToString()); } continue; } } // if(((uint)eventFlags & (uint)CommEventFlags.ERR) != 0) #endregion #region >>>> line status checking <<<< // check for status changes uint status = 0; m_CommAPI.GetCommModemStatus(hPort, ref status); // check the CTS if (((uint)eventFlags & (uint)CommEventFlags.CTS) != 0) { if (CTSChange != null) { CTSChange((status & (uint)CommModemStatusFlags.MS_CTS_ON) != 0); } } // check the DSR if (((uint)eventFlags & (uint)CommEventFlags.DSR) != 0) { if (DSRChange != null) { DSRChange((status & (uint)CommModemStatusFlags.MS_DSR_ON) != 0); } } // check for a RING if (((uint)eventFlags & (uint)CommEventFlags.RING) != 0) { if (RingChange != null) { RingChange((status & (uint)CommModemStatusFlags.MS_RING_ON) != 0); } } // check for a RLSD if (((uint)eventFlags & (uint)CommEventFlags.RLSD) != 0) { if (RLSDChange != null) { RLSDChange((status & (uint)CommModemStatusFlags.MS_RLSD_ON) != 0); } } // check for TXEMPTY if (((uint)eventFlags & (uint)CommEventFlags.TXEMPTY) != 0) { if (TxDone != null) { TxDone(); } } // check for RXFLAG if (((uint)eventFlags & (uint)CommEventFlags.RXFLAG) != 0) { if (FlagCharReceived != null) { FlagCharReceived(); } } // check for POWER if (((uint)eventFlags & (uint)CommEventFlags.POWER) != 0) { if (PowerEvent != null) { PowerEvent(); } } // check for high-water state if ((eventFlags & CommEventFlags.RX80FULL) != 0) { if (HighWater != null) { HighWater(); } } #endregion #region >>>> Receive data subsection <<<< // check for RXCHAR if ((eventFlags & CommEventFlags.RXCHAR) != 0) { do { // make sure the port handle is valid if (hPort == (IntPtr)CommAPI.INVALID_HANDLE_VALUE) { bytesread = 0; break; } // data came in, put it in the buffer and set the event if (!m_CommAPI.ReadFile(hPort, readbuffer, rxBufferSize, ref bytesread, rxOverlapped)) { string errString = String.Format("ReadFile Failed: {0}", Marshal.GetLastWin32Error()); if (OnError != null) { OnError(errString); } return; } if (bytesread >= 1) { // take the mutex rxBufferBusy.WaitOne(); // put the data into the fifo // this *may* be a perf problem and needs testing for (int b = 0; b < bytesread; b++) { rxFIFO.Enqueue(readbuffer[b]); } // get the FIFO length int fifoLength = rxFIFO.Count; // release the mutex rxBufferBusy.ReleaseMutex(); // fire the DataReceived event every RThreshold bytes if ((DataReceived != null) && (rthreshold != 0) && (fifoLength >= rthreshold)) { DataReceived(); } } } while (bytesread > 0); } // if((eventFlags & CommEventFlags.RXCHAR) != 0) #endregion } // while(true) #endregion } // try catch (Exception e) { if (rxOverlapped != IntPtr.Zero) { LocalFree(rxOverlapped); } if (OnError != null) { OnError(e.Message); } return; } }
private static extern int WinClearCommError(IntPtr hFile, ref CommErrorFlags lpErrors, CommStat lpStat);
override internal bool ClearCommError(IntPtr hPort, ref CommErrorFlags flags, CommStat stat) { return Convert.ToBoolean(WinClearCommError(hPort, ref flags, stat)); }
internal virtual bool ClearCommError(IntPtr hPort, ref CommErrorFlags flags, CommStat stat){return false;}
internal virtual bool ClearCommError(IntPtr hPort, ref CommErrorFlags flags, CommStat stat) { return(false); }
private void CommEventThread() { CommEventFlags eventFlags = new CommEventFlags(); byte[] readbuffer = new Byte[rxBufferSize]; int bytesread = 0; AutoResetEvent rxevent = new AutoResetEvent(false); // specify the set of events to be monitored for the port. if(CommAPI.FullFramework) { m_CommAPI.SetCommMask(hPort, CommEventFlags.ALLPC); // set up the overlapped IO OVERLAPPED o = new OVERLAPPED(); rxOverlapped = LocalAlloc(0x40, Marshal.SizeOf(o)); o.Offset = 0; o.OffsetHigh = 0; o.hEvent = rxevent.Handle; Marshal.StructureToPtr(o, rxOverlapped, true); } else { m_CommAPI.SetCommMask(hPort, CommEventFlags.ALLCE); } try { // let Open() know we're started threadStarted.Set(); #region >>>> thread loop <<<< while(hPort != (IntPtr)CommAPI.INVALID_HANDLE_VALUE) { // wait for a Comm event if(!m_CommAPI.WaitCommEvent(hPort, ref eventFlags)) { int e = Marshal.GetLastWin32Error(); if(e == (int)APIErrors.ERROR_IO_PENDING) { // IO pending so just wait and try again rxevent.WaitOne(); Thread.Sleep(0); continue; } if(e == (int)APIErrors.ERROR_INVALID_HANDLE) { // Calling Port.Close() causes hPort to become invalid // Since Thread.Abort() is unsupported in the CF, we must // accept that calling Close will throw an error here. // Close signals the closeEvent, so wait on it // We wait 1 second, though Close should happen much sooner int eventResult = m_CommAPI.WaitForSingleObject(closeEvent, 1000); if(eventResult == (int)APIConstants.WAIT_OBJECT_0) { // the event was set so close was called hPort = (IntPtr)CommAPI.INVALID_HANDLE_VALUE; // reset our ResetEvent for the next call to Open threadStarted.Reset(); if(isOpen) // this should not be the case...if so, throw an exception for the owner { string error = String.Format("Wait Failed: {0}", e); throw new CommPortException(error); } return; } } // WaitCommEvent failed // 995 means an exit was requested (thread killed) if(e == 995) { return; } else { string error = String.Format("Wait Failed: {0}", e); throw new CommPortException(error); } } // Re-specify the set of events to be monitored for the port. if(CommAPI.FullFramework) { m_CommAPI.SetCommMask(hPort, CommEventFlags.ALLPC); } else { m_CommAPI.SetCommMask(hPort, CommEventFlags.ALLCE); } // check the event for errors #region >>>> error checking <<<< if(((uint)eventFlags & (uint)CommEventFlags.ERR) != 0) { CommErrorFlags errorFlags = new CommErrorFlags(); CommStat commStat = new CommStat(); // get the error status if(!m_CommAPI.ClearCommError(hPort, ref errorFlags, commStat)) { // ClearCommError failed! string error = String.Format("ClearCommError Failed: {0}", Marshal.GetLastWin32Error()); throw new CommPortException(error); } if(((uint)errorFlags & (uint)CommErrorFlags.BREAK) != 0) { // BREAK can set an error, so make sure the BREAK bit is set an continue eventFlags |= CommEventFlags.BREAK; } else { // we have an error. Build a meaningful string and throw an exception StringBuilder s = new StringBuilder("UART Error: ", 80); if ((errorFlags & CommErrorFlags.FRAME) != 0) { s = s.Append("Framing,"); } if ((errorFlags & CommErrorFlags.IOE) != 0) { s = s.Append("IO,"); } if ((errorFlags & CommErrorFlags.OVERRUN) != 0) { s = s.Append("Overrun,"); } if ((errorFlags & CommErrorFlags.RXOVER) != 0) { s = s.Append("Receive Overflow,"); } if ((errorFlags & CommErrorFlags.RXPARITY) != 0) { s = s.Append("Parity,"); } if ((errorFlags & CommErrorFlags.TXFULL) != 0) { s = s.Append("Transmit Overflow,"); } // no known bits are set if(s.Length == 12) { s = s.Append("Unknown"); } // raise an error event if(OnError != null) OnError(s.ToString()); continue; } } // if(((uint)eventFlags & (uint)CommEventFlags.ERR) != 0) #endregion #region >>>> Receive data subsection <<<< // check for RXCHAR if((eventFlags & CommEventFlags.RXCHAR) != 0) { do { // make sure the port handle is valid if(hPort == (IntPtr)CommAPI.INVALID_HANDLE_VALUE) { bytesread = 0; break; } // data came in, put it in the buffer and set the event if (!m_CommAPI.ReadFile(hPort, readbuffer, rxBufferSize, ref bytesread, rxOverlapped)) { string errString = String.Format("ReadFile Failed: {0}", Marshal.GetLastWin32Error()); if(OnError != null) OnError(errString); return; } if (bytesread >= 1) { // take the mutex rxBufferBusy.WaitOne(); // put the data into the fifo // this *may* be a perf problem and needs testing for(int b = 0 ; b < bytesread ; b++) rxFIFO.Enqueue(readbuffer[b]); // get the FIFO length int fifoLength = rxFIFO.Count; // release the mutex rxBufferBusy.ReleaseMutex(); // fire the DataReceived event every RThreshold bytes if((DataReceived != null) && (rthreshold != 0) && (fifoLength >= rthreshold)) { DataReceived(); } } } while (bytesread > 0); } // if((eventFlags & CommEventFlags.RXCHAR) != 0) #endregion #region >>>> line status checking <<<< // check for status changes uint status = 0; m_CommAPI.GetCommModemStatus(hPort, ref status); // check the CTS if(((uint)eventFlags & (uint)CommEventFlags.CTS) != 0) { if(CTSChange != null) CTSChange((status & (uint)CommModemStatusFlags.MS_CTS_ON) != 0); } // check the DSR if(((uint)eventFlags & (uint)CommEventFlags.DSR) != 0) { if(DSRChange != null) DSRChange((status & (uint)CommModemStatusFlags.MS_DSR_ON) != 0); } // check for a RING if(((uint)eventFlags & (uint)CommEventFlags.RING) != 0) { if(RingChange != null) RingChange((status & (uint)CommModemStatusFlags.MS_RING_ON) != 0); } // check for a RLSD if(((uint)eventFlags & (uint)CommEventFlags.RLSD) != 0) { if(RLSDChange != null) RLSDChange((status & (uint)CommModemStatusFlags.MS_RLSD_ON) != 0); } // check for TXEMPTY if(((uint)eventFlags & (uint)CommEventFlags.TXEMPTY) != 0) if(TxDone != null) { TxDone(); } // check for RXFLAG if(((uint)eventFlags & (uint)CommEventFlags.RXFLAG) != 0) if(FlagCharReceived != null) { FlagCharReceived(); } // check for POWER if(((uint)eventFlags & (uint)CommEventFlags.POWER) != 0) if(PowerEvent != null) { PowerEvent(); } // check for high-water state if((eventFlags & CommEventFlags.RX80FULL) != 0) if(HighWater != null) { HighWater(); } #endregion } // while(true) #endregion } // try catch(Exception e) { if(rxOverlapped != IntPtr.Zero) LocalFree(rxOverlapped); if(OnError != null) OnError(e.Message); return; } }
/// <summary> /// Opens a new serial port connection. /// </summary> public void Open() { if(this.mIsOpen) throw new InvalidOperationException("Comm Port is already open!"); if(CommAPI.FullFramework) { // set up the overlapped tx IO OVERLAPPED o = new OVERLAPPED(); this.mTxOverlapped = LocalAlloc(0x40, Marshal.SizeOf(o)); o.Offset = 0; o.OffsetHigh = 0; o.hEvent = IntPtr.Zero; Marshal.StructureToPtr(o, this.mTxOverlapped, true); } hPort = m_CommAPI.CreateFile(this.mPortName); if(hPort == (IntPtr)CommAPI.INVALID_HANDLE_VALUE) { int e = Marshal.GetLastWin32Error(); if(e == (int)APIErrors.ERROR_ACCESS_DENIED) { // port is unavailable throw new ApplicationException("ERROR_ACCESS_DENIED"); } // ClearCommError failed! string error = String.Format("CreateFile Failed: {0}", e); throw new ApplicationException(error); } this.mIsOpen = true; // clear errors CommErrorFlags errorFlags = new CommErrorFlags(); CommStat commStat = new CommStat(); if(!m_CommAPI.ClearCommError(hPort, ref errorFlags, commStat)) { throw new ApplicationException("Failed to clear error/read"); } // set queue sizes m_CommAPI.SetupComm(hPort, this.mRxBufferSize, this.mTxBufferSize); // update dcb this.UpdateSettings(); // store some state values this.mInBreak = false; // read/write timeouts this.UpdateTimeouts(); // start the receive thread this.mEventThread = new Thread(new ThreadStart(CommEventThread)); this.mEventThread.Priority = ThreadPriority.Normal; //by design this.mEventThread.Start(); // wait for the thread to actually get spun up this.mThreadStarted.WaitOne(); }
private void ProcessEvents(object flags){ CommEventFlags eventFlags = (CommEventFlags)flags; // check the event for errors #region >>>> error checking <<<< if(((uint)eventFlags & (uint)CommEventFlags.ERR) != 0) { CommErrorFlags errorFlags = new CommErrorFlags(); CommStat commStat = new CommStat(); // get the error status if(!m_CommAPI.ClearCommError(hPort, ref errorFlags, commStat)) { // ClearCommError failed! string error = String.Format("ClearCommError Failed: {0}", Marshal.GetLastWin32Error()); throw new ApplicationException(error); } if(((uint)errorFlags & (uint)CommErrorFlags.BREAK) != 0) { // BREAK can set an error, so make sure the BREAK bit is set an continue eventFlags |= CommEventFlags.BREAK; } else { // we have an error. Build a meaningful string and throw an exception if (ErrorReceived != null){ if ((errorFlags & CommErrorFlags.TXFULL) != 0) { ErrorReceived(this,new SerialErrorReceivedEventArgs(SerialError.TXFull)); } if ((errorFlags & CommErrorFlags.RXOVER) != 0) { ErrorReceived(this,new SerialErrorReceivedEventArgs(SerialError.RXOver)); } if ((errorFlags & CommErrorFlags.OVERRUN) != 0) { ErrorReceived(this,new SerialErrorReceivedEventArgs(SerialError.Overrun)); } if ((errorFlags & CommErrorFlags.RXPARITY) != 0) { ErrorReceived(this,new SerialErrorReceivedEventArgs(SerialError.RXParity)); } if ((errorFlags & CommErrorFlags.FRAME) != 0) { ErrorReceived(this,new SerialErrorReceivedEventArgs(SerialError.Frame)); } } return; } } // if(((uint)eventFlags & (uint)CommEventFlags.ERR) != 0) #endregion #region >>>> Receive data subsection <<<< // check for RXCHAR if (DataReceived != null){ if((eventFlags & CommEventFlags.RXCHAR) != 0) { DataReceived(this,new SerialDataReceivedEventArgs(SerialData.Chars)); } if(((uint)eventFlags & 2) != 0) { DataReceived(this,new SerialDataReceivedEventArgs(SerialData.Eof)); } } #endregion #region >>>> line status checking <<<< if(PinChanged != null){ // check the CTS if(((uint)eventFlags & (uint)CommEventFlags.CTS) != 0) { PinChanged(this,new SerialPinChangedEventArgs(SerialPinChange.CtsChanged)); } // check the DSR if(((uint)eventFlags & (uint)CommEventFlags.DSR) != 0) { PinChanged(this,new SerialPinChangedEventArgs(SerialPinChange.DsrChanged)); } // check for a RING if(((uint)eventFlags & (uint)CommEventFlags.RING) != 0) { PinChanged(this,new SerialPinChangedEventArgs(SerialPinChange.Ring)); } // check for a RLSD if(((uint)eventFlags & (uint)CommEventFlags.RLSD) != 0) { PinChanged(this,new SerialPinChangedEventArgs(SerialPinChange.CDChanged)); } // check for a break if(((uint)eventFlags & (uint)CommEventFlags.BREAK) != 0) { PinChanged(this,new SerialPinChangedEventArgs(SerialPinChange.Break)); } } #endregion }
private void CommEventThread() { byte[] buffer = new byte[this.rxBufferSize]; int cbRead = 0; new AutoResetEvent(false); if (CommAPI.FullFramework) { this.m_CommAPI.SetCommMask(this.hPort, CommEventFlags.ALLPC); } else { this.m_CommAPI.SetCommMask(this.hPort, CommEventFlags.ALLCE); } this.threadStarted.Set(); StringBuilder builder = new StringBuilder("", 80); while (this.hPort != ((IntPtr) (-1))) { try { CommErrorFlags flags = 0; CommStat stat = new CommStat(); if (!this.m_CommAPI.ClearCommError(this.hPort, ref flags, stat)) { Thread.Sleep(20); } else if (stat.cbInQue == 0) { Thread.Sleep(20); } else { builder.Append("UART Error: "); if ((flags & CommErrorFlags.FRAME) != 0) { builder = builder.Append("Framing,"); } if ((flags & CommErrorFlags.IOE) != 0) { builder = builder.Append("IO,"); } if ((flags & CommErrorFlags.OVERRUN) != 0) { builder = builder.Append("Overrun,"); } if ((flags & CommErrorFlags.RXOVER) != 0) { builder = builder.Append("Receive Overflow,"); } if ((flags & CommErrorFlags.RXPARITY) != 0) { builder = builder.Append("Parity,"); } if ((flags & CommErrorFlags.TXFULL) != 0) { builder = builder.Append("Transmit Overflow,"); } if ((flags & CommErrorFlags.BREAK) != 0) { builder = builder.Append("Break,"); } if (builder.Length == 12) { builder = builder.Append("Unknown"); } if ((this.OnError != null) && (flags != 0)) { this.OnError(builder.ToString()); } if (stat.cbInQue >= this.rxBufferSize) { this.m_CommAPI.ReadFile(this.hPort, buffer, this.rxBufferSize, ref cbRead, IntPtr.Zero); } else { this.m_CommAPI.ReadFile(this.hPort, buffer, (int) stat.cbInQue, ref cbRead, IntPtr.Zero); } if (cbRead >= 1) { this.rxBufferBusy.WaitOne(); for (int i = 0; i < cbRead; i++) { this.rxFIFO.Enqueue(buffer[i]); } int count = this.rxFIFO.Count; this.rxBufferBusy.ReleaseMutex(); if (((this.DataReceived != null) && (this.rthreshold != 0)) && (count >= this.rthreshold)) { this.DataReceived(); } } builder.Remove(0, builder.Length); Thread.Sleep(1); } continue; } catch (Exception exception) { if (this.rxOverlapped != IntPtr.Zero) { LocalFree(this.rxOverlapped); } if (this.OnError != null) { this.OnError(exception.Message); } continue; } } }
public bool Close() { CommErrorFlags flags; if (this.txOverlapped != IntPtr.Zero) { LocalFree(this.txOverlapped); this.txOverlapped = IntPtr.Zero; } if (this.rxOverlapped != IntPtr.Zero) { LocalFree(this.rxOverlapped); this.rxOverlapped = IntPtr.Zero; } if (this.hPort == IntPtr.Zero) { return false; } int num = 0; Label_0068: flags = 0; CommStat stat = new CommStat(); if (!this.m_CommAPI.ClearCommError(this.hPort, ref flags, stat) || (stat.cbOutQue != 0)) { Thread.Sleep(1); if (num < 3) { num++; Thread.Sleep(10); goto Label_0068; } } this.m_CommAPI.PurgeComm(this.hPort, 0); this.m_CommAPI.CloseHandle(this.hPort); this.m_CommAPI.SetEvent(this.closeEvent); this.isOpen = false; this.hPort = (IntPtr) (-1); return true; }
private void CommEventThread() { byte[] buffer = new byte[this.rxBufferSize]; int cbRead = 0; new AutoResetEvent(false); if (CommAPI.FullFramework) { this.m_CommAPI.SetCommMask(this.hPort, CommEventFlags.ALLPC); } else { this.m_CommAPI.SetCommMask(this.hPort, CommEventFlags.ALLCE); } this.threadStarted.Set(); StringBuilder builder = new StringBuilder("", 80); while (this.hPort != ((IntPtr)(-1))) { try { CommErrorFlags flags = 0; CommStat stat = new CommStat(); if (!this.m_CommAPI.ClearCommError(this.hPort, ref flags, stat)) { Thread.Sleep(20); } else if (stat.cbInQue == 0) { Thread.Sleep(20); } else { builder.Append("UART Error: "); if ((flags & CommErrorFlags.FRAME) != 0) { builder = builder.Append("Framing,"); } if ((flags & CommErrorFlags.IOE) != 0) { builder = builder.Append("IO,"); } if ((flags & CommErrorFlags.OVERRUN) != 0) { builder = builder.Append("Overrun,"); } if ((flags & CommErrorFlags.RXOVER) != 0) { builder = builder.Append("Receive Overflow,"); } if ((flags & CommErrorFlags.RXPARITY) != 0) { builder = builder.Append("Parity,"); } if ((flags & CommErrorFlags.TXFULL) != 0) { builder = builder.Append("Transmit Overflow,"); } if ((flags & CommErrorFlags.BREAK) != 0) { builder = builder.Append("Break,"); } if (builder.Length == 12) { builder = builder.Append("Unknown"); } if ((this.OnError != null) && (flags != 0)) { this.OnError(builder.ToString()); } if (stat.cbInQue >= this.rxBufferSize) { this.m_CommAPI.ReadFile(this.hPort, buffer, this.rxBufferSize, ref cbRead, IntPtr.Zero); } else { this.m_CommAPI.ReadFile(this.hPort, buffer, (int)stat.cbInQue, ref cbRead, IntPtr.Zero); } if (cbRead >= 1) { this.rxBufferBusy.WaitOne(); for (int i = 0; i < cbRead; i++) { this.rxFIFO.Enqueue(buffer[i]); } int count = this.rxFIFO.Count; this.rxBufferBusy.ReleaseMutex(); if (((this.DataReceived != null) && (this.rthreshold != 0)) && (count >= this.rthreshold)) { this.DataReceived(); } } builder.Remove(0, builder.Length); Thread.Sleep(1); } continue; } catch (Exception exception) { if (this.rxOverlapped != IntPtr.Zero) { LocalFree(this.rxOverlapped); } if (this.OnError != null) { this.OnError(exception.Message); } continue; } } }