private void Init() { // create a system event for synchronizing Closing closeEvent = CommAPI.CreateEvent(true, false, closeEventName); rxBuffer = new byte[rxBufferSize + 1000]; txBuffer = new byte[txBufferSize]; portSettings = new DetailedPortSettings(); }
public bool Close() { if (!isOpen) { return(false); } if (CommAPI.CloseHandle(hPort)) { CommAPI.SetEvent(closeEvent); isOpen = false; hPort = (IntPtr)CommAPI.INVALID_HANDLE_VALUE; CommAPI.SetEvent(closeEvent); return(true); } return(false); }
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; } }
public bool Open() { if (isOpen) { return(false); } hPort = CommAPI.CreateFile(portName); if (hPort == (IntPtr)CommAPI.INVALID_HANDLE_VALUE) { int e = Marshal.GetLastWin32Error(); if (e == (int)APIErrors.ERROR_ACCESS_DENIED) { // port is unavailable return(false); } if (e == (int)APIErrors.ERROR_PORT_UNAVAIL) { // port is unavailable return(false); } // ClearCommError failed! string error = String.Format("CreateFile Failed: {0}", e); throw new CommPortException(error); } isOpen = true; // set queue sizes CommAPI.SetupComm(hPort, rxBufferSize, txBufferSize); // transfer the port settings to a DCB structure dcb.BaudRate = (uint)portSettings.BasicSettings.BaudRate; dcb.ByteSize = portSettings.BasicSettings.ByteSize; dcb.EofChar = (sbyte)portSettings.EOFChar; dcb.ErrorChar = (sbyte)portSettings.ErrorChar; dcb.EvtChar = (sbyte)portSettings.EVTChar; dcb.fAbortOnError = portSettings.AbortOnError; dcb.fBinary = true; dcb.fDsrSensitivity = portSettings.DSRSensitive; dcb.fDtrControl = (DCB.DtrControlFlags)portSettings.DTRControl; dcb.fErrorChar = portSettings.ReplaceErrorChar; dcb.fInX = portSettings.InX; dcb.fNull = portSettings.DiscardNulls; dcb.fOutX = portSettings.OutX; dcb.fOutxCtsFlow = portSettings.OutCTS; dcb.fOutxDsrFlow = portSettings.OutDSR; dcb.fParity = (portSettings.BasicSettings.Parity == Parity.none) ? false : true; dcb.fRtsControl = (DCB.RtsControlFlags)portSettings.RTSControl; dcb.fTXContinueOnXoff = portSettings.TxContinueOnXOff; dcb.Parity = (byte)portSettings.BasicSettings.Parity; dcb.StopBits = (byte)portSettings.BasicSettings.StopBits; dcb.XoffChar = (sbyte)portSettings.XoffChar; dcb.XonChar = (sbyte)portSettings.XonChar; dcb.XonLim = dcb.XoffLim = (ushort)(rxBufferSize / 10); CommAPI.SetCommState(hPort, dcb); // store some state values brk = 0; dtr = dcb.fDtrControl == DCB.DtrControlFlags.Enable ? 1 : 0; rts = dcb.fRtsControl == DCB.RtsControlFlags.Enable ? 1 : 0; // set the Comm timeouts CommTimeouts ct = new CommTimeouts(); // reading we'll return immediately // this doesn't seem to work as documented ct.ReadIntervalTimeout = uint.MaxValue; // this = 0xffffffff // ct.ReadIntervalTimeout = 2; ct.ReadTotalTimeoutConstant = 2; ct.ReadTotalTimeoutMultiplier = uint.MaxValue; // writing we'll give 5 seconds ct.WriteTotalTimeoutConstant = 5; ct.WriteTotalTimeoutMultiplier = 0; CommAPI.SetCommTimeouts(hPort, ct); // start the receive thread eventThread = new Thread(new ThreadStart(CommEventThread)); eventThread.Priority = ThreadPriority.AboveNormal; eventThread.Start(); // wait for the thread to actually get spun up threadStarted.WaitOne(); return(true); }