Beispiel #1
0
        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();
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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;
            }
        }
Beispiel #4
0
        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);
        }