internal static bool ClearCommError(IntPtr hPort, ref CommErrorFlags flags, CommStat stat) { if (FullFramework) { return(Convert.ToBoolean(WinClearCommError(hPort, ref flags, stat))); } else { return(Convert.ToBoolean(CEClearCommError(hPort, ref flags, stat))); } }
/// <summary> /// Runs solely on a separate thread waiting on events to come in /// from the communication port (OS) and handles those events. /// </summary> /// <remarks>Assumption made that port is open.</remarks> /// <exception cref="System.Exception"> /// Thrown when a communication port error or a /// system exception occurs. /// </exception> /// Revision History /// MM/DD/YY who Version Issue# Description /// -------- --- ------- ------ --------------------------------------- /// 08/01/05 bdm 7.13.00 N/A Created /// 08/17/06 mrj 7.35.00 Removed unused events /// 03/02/07 mrj 8.00.16 Changed when the FlagCharReceived event /// is fired. /// private void CommEventThread() { CommEventFlags eventFlags = new CommEventFlags(); byte[] readbuffer = new Byte[m_uintRxBufSz]; string strErrDesc; int intErr; try { //Specify the set of events to be monitored for the port. PortAPI.SetCommMask(m_hPort, CommEventFlags.ALL); //Let Open() know the tread has started m_rxThreadStartedEvent.Set(); while (IsOpen) { //Wait for a Comm event to happen if (false == PortAPI.WaitCommEvent(m_hPort, ref eventFlags)) { //WaitCommEvent failed - find out why intErr = Marshal.GetLastWin32Error(); if (intErr == (int)APIErrors.ERROR_IO_PENDING) { //IO pending so just wait and try again. //Suspend thread to allow other threads to execute. Thread.Sleep(0); continue; } if (intErr == (int)APIErrors.ERROR_INVALID_HANDLE) { //Calling Communication.Close() causes m_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 m_ptrCloseEvent, so wait on it //We wait 1 second, though Close should happen //much sooner int intEventResult = PortAPI.WaitForSingleObject(m_ptrCloseEvent, 1000); if (intEventResult == (int)APIConstants.WAIT_OBJECT_0) { // the event was set so close was called m_hPort = (IntPtr)PortAPI.INVALID_HANDLE_VALUE; // reset our ResetEvent for the next call //to Open() m_rxThreadStartedEvent.Reset(); return; } } //WaitCommEvent failed! strErrDesc = m_rmStrings.GetString("WAIT_COMM_EVENT_FAILED"); strErrDesc = string.Format(strErrDesc, intErr); throw (new Exception(strErrDesc)); } //Re-specify the set of events to be monitored for the port. PortAPI.SetCommMask(m_hPort, CommEventFlags.ALL); //Check the event for errors if (((uint)eventFlags & (uint)CommEventFlags.ERR) != 0) { CommErrorFlags errorFlags = new CommErrorFlags(); CommStat commStat = new CommStat(); //Get the error status if (false == PortAPI.ClearCommError(m_hPort, ref errorFlags, commStat)) { //ClearCommError failed! intErr = Marshal.GetLastWin32Error(); strErrDesc = m_rmStrings.GetString("CLEAR_COMM_ERROR_FAILED"); strErrDesc = string.Format(strErrDesc, intErr); throw (new Exception(strErrDesc)); } 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 strMsg = new StringBuilder("UART Error: ", 80); if ((errorFlags & CommErrorFlags.FRAME) != 0) { strMsg = strMsg.Append("Framing,"); } if ((errorFlags & CommErrorFlags.IOE) != 0) { strMsg = strMsg.Append("IO,"); } if ((errorFlags & CommErrorFlags.OVERRUN) != 0) { strMsg = strMsg.Append("Overrun,"); } if ((errorFlags & CommErrorFlags.RXOVER) != 0) { strMsg = strMsg.Append("Receive Overflow,"); } if ((errorFlags & CommErrorFlags.RXPARITY) != 0) { strMsg = strMsg.Append("Parity,"); } if ((errorFlags & CommErrorFlags.TXFULL) != 0) { strMsg = strMsg.Append("Transmit Overflow,"); } //No known bits are set if (strMsg.Length == 12) { strMsg = strMsg.Append("Unknown"); } //Raise an error event to anyone listening //if (null != OnError) //OnError(strMsg.ToString()); continue; } } //End if( ( (uint)eventFlags & (uint)CommEventFlags.ERR ) != 0 ) //Check for status changes //08-12-05 bdm: Frankly, not sure for what purpose status = 0. // But hesitate to modify since the code was borrowed // and there does not exist a client that catches // these events. //uint status = 0; //Check for RXFLAG if (((uint)eventFlags & (uint)CommEventFlags.RXFLAG) != 0) { //if (null != FlagCharReceived) //FlagCharReceived(); } //Check for RXCHAR if ((eventFlags & CommEventFlags.RXCHAR) != 0) { //Let the client know that we have received a character if (null != FlagCharReceived) { FlagCharReceived(); } } } // while(true) } // try catch (Exception e) { throw (e); } }
extern private static int WinClearCommError(IntPtr hFile, ref CommErrorFlags lpErrors, CommStat lpStat);