internal static bool WaitCommEvent(IntPtr hPort, ref CommEventFlags flags) { if (FullFramework) { return(Convert.ToBoolean(WinWaitCommEvent(hPort, ref flags, IntPtr.Zero))); } else { return(Convert.ToBoolean(CEWaitCommEvent(hPort, ref flags, IntPtr.Zero))); } }
internal static bool SetCommMask(IntPtr hPort, CommEventFlags dwEvtMask) { if (FullFramework) { return(Convert.ToBoolean(WinSetCommMask(hPort, dwEvtMask))); } else { if (CommEventFlags.ALL == dwEvtMask) { //This is a CE device so include the POWER event dwEvtMask = CommEventFlags.ALL_CE; } return(Convert.ToBoolean(CESetCommMask(hPort, dwEvtMask))); } }
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; } }
/// <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); } }
private static extern int WinWaitCommEvent(IntPtr hFile, ref CommEventFlags lpEvtMask, IntPtr lpOverlapped);
private static extern int WinSetCommMask(IntPtr handle, CommEventFlags dwEvtMask);
override internal bool SetCommMask(IntPtr hPort, CommEventFlags dwEvtMask) { return Convert.ToBoolean(WinSetCommMask(hPort, dwEvtMask)); }
private void CommEventThread() { CommEventFlags eventFlags = new CommEventFlags(); byte[] readbuffer = new byte[1000]; int bytesread = 0; // specify the set of events to be monitored for the port. CommAPI.SetCommMask(hPort, CommEventFlags.RXCHAR); try { // let Open() know we're started threadStarted.Set(); while (hPort != (IntPtr)CommAPI.INVALID_HANDLE_VALUE) { try { // wait for a Comm event if (!CommAPI.WaitCommEvent(hPort, ref eventFlags)) { int e = Marshal.GetLastWin32Error(); if (e == (int)APIErrors.ERROR_IO_PENDING) { // IO pending so just wait and try again 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 = 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(); return; } } // WaitCommEvent failed! string error = String.Format("Wait Failed: {0}", e); throw new CommPortException(error); } } catch (Exception e) { throw e; } try { // Re-specify the set of events to be monitored for the port. CommAPI.SetCommMask(hPort, CommEventFlags.RXCHAR); } catch (Exception e) { throw e; } // check for RXCHAR if ((eventFlags & CommEventFlags.RXCHAR) != 0) { if (DataReceived != null) { try { // data came in, put it in the buffer and set the event CommAPI.ReadFile(hPort, readbuffer, 1000, ref bytesread); } catch (Exception e) { throw e; } if (bytesread >= 1) { rxBufferBusy.WaitOne(); try { // store the byte in out buffer and increment the pointer Array.Copy(readbuffer, 0, rxBuffer, (int)prxBuffer, (int)bytesread); prxBuffer += (uint)bytesread; } catch (Exception e) { throw e; } finally { rxBufferBusy.ReleaseMutex(); } { // prxBuffer gets reset when the Input value is read. (FIFO) if (DataReceived != null) { DataReceived(); } } } } } } // while(true) } // try catch (Exception e) { throw e; } }
private static extern int CESetCommMask(IntPtr handle, CommEventFlags dwEvtMask);
internal virtual bool WaitCommEvent(IntPtr hPort, ref CommEventFlags flags){return false;}
internal virtual bool SetCommMask(IntPtr hPort, CommEventFlags dwEvtMask) { return(false); }
internal virtual bool WaitCommEvent(IntPtr hPort, ref CommEventFlags flags) { 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; } }
private void CommEventThread() { CommEventFlags eventFlags = new CommEventFlags(); AutoResetEvent rxevent = new AutoResetEvent(false); // specify the set of events to be monitored for the port. bool b; if(CommAPI.FullFramework) { b = m_CommAPI.SetCommMask(hPort, CommEventFlags.ALLPC); // set up the overlapped IO OVERLAPPED o = new OVERLAPPED(); this.mRxOverlapped = LocalAlloc(0x40, Marshal.SizeOf(o)); o.Offset = 0; o.OffsetHigh = 0; o.hEvent = rxevent.Handle; Marshal.StructureToPtr(o, this.mRxOverlapped, true); } else { b = m_CommAPI.SetCommMask(hPort, CommEventFlags.ALLCE_2); } try { // let Open() know we're started this.mThreadStarted.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 this.mCloseEvent, so wait on it // We wait 1 second, though Close should happen much sooner int eventResult = m_CommAPI.WaitForSingleObject(this.mCloseEvent, 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 this.mThreadStarted.Reset(); if(this.mIsOpen) { // this should not be the case...if so, throw an exception for the owner string error = String.Format("Wait Failed: {0}", e); throw new ApplicationException(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 ApplicationException(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); } // Process the flag - extracted main handling into its own method //ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessEvents), eventFlags); this.ProcessEvents(eventFlags); } // while(not invalid handle) #endregion } // try catch{ if(this.mRxOverlapped != IntPtr.Zero) LocalFree(this.mRxOverlapped); throw; } }
/// <summary> /// /// </summary> /// <param name="someByteData"></param> /// <returns></returns> public int GrabData(byte[] someByteData) { bread = 0; if (isThreaded) { Console.WriteLine ("SHOULD NOT BE CALLING THIS BECAUSE NOT DIRECT READ"); } try { grabEventFlags = CommEventFlags.RXCHAR; isNotPending = false; while (isNotPending) { if(!m_CommAPI.WaitCommEvent(hPort, ref grabEventFlags)) { int e = Marshal.GetLastWin32Error(); if(e == (int)APIErrors.ERROR_IO_PENDING) { // IO pending so just wait and try again grabRxevent.WaitOne(); Thread.Sleep(0); isNotPending = false; } } else isNotPending = true; } int tbread = bread; // make sure the port handle is valid if(hPort == (IntPtr)CommAPI.INVALID_HANDLE_VALUE) { Console.WriteLine ("Invalid port"); bread = 0; } // data came in, put it in the buffer and set the event else if (!m_CommAPI.ReadFile(hPort, grabBytes, rxBufferSize, ref tbread, rxOverlapped)) { bread = 0; string errString = String.Format("ReadFile Failed: {0}", Marshal.GetLastWin32Error()); Console.WriteLine ("ERROR: " + errString); // if(OnError != null) // OnError(errString); } bread = tbread; if (bread >= 1) { //take the mutex rxBufferBusy.WaitOne(); if (someByteData.Length < grabBytes.Length) { Console.WriteLine ("ERROR BUFFER SIZE"); } // put the data into the fifo // this *may* be a perf problem and needs testing for(int b = 0 ; b < bread ; b++) someByteData[b] = grabBytes[b]; // release the mutex rxBufferBusy.ReleaseMutex(); } } catch(Exception e) { Console.WriteLine ("SOME TYPE OF EXCEPTION: " + e.Message); bread = 0; } return bread; }
internal override bool SetCommMask(IntPtr hPort, CommEventFlags dwEvtMask) { return(Convert.ToBoolean(CESetCommMask(hPort, dwEvtMask))); }
internal override bool WaitCommEvent(IntPtr hPort, ref CommEventFlags flags) { return(Convert.ToBoolean(CEWaitCommEvent(hPort, ref flags, IntPtr.Zero))); }
internal virtual bool SetCommMask(IntPtr hPort, CommEventFlags dwEvtMask) {return false;}
private static extern int CEWaitCommEvent(IntPtr hFile, ref CommEventFlags lpEvtMask, IntPtr lpOverlapped);
override internal bool WaitCommEvent(IntPtr hPort, ref CommEventFlags flags) { return Convert.ToBoolean(WinWaitCommEvent(hPort, ref flags, IntPtr.Zero)); }