Beispiel #1
0
        public void GivenNativeSerialPort_WhenDisposeTwice_ThenInnerPortDisposedOnce()
        {
            // Arrange
            var sut = new NativeSerialPort(
                "COM1",
                9600,
                Parity.None,
                8,
                StopBits.One,
                Handshake.None,
                new TimeSpan(0, 0, 5),
                new TimeSpan(0, 0, 5));
            var disposeCount = 0;

            sut.InnerPort.Disposed += (object sender, EventArgs e) =>
            {
                disposeCount += 1;
            };

            // Act
            sut.Dispose();
            sut.Dispose();

            // Assert
            Assert.Equal(1, disposeCount);
        }
Beispiel #2
0
        public void GivenNativeSerialPort_WhenDispose_ThenInnerPortDisposed()
        {
            // Arrange
            var sut = new NativeSerialPort(
                "COM1",
                9600,
                Parity.None,
                8,
                StopBits.One,
                Handshake.None,
                new TimeSpan(0, 0, 5),
                new TimeSpan(0, 0, 5));
            var disposed = false;

            sut.InnerPort.Disposed += (object sender, EventArgs e) =>
            {
                disposed = true;
            };

            // Act
            sut.Dispose();

            // Assert
            Assert.True(disposed);
        }
 private void SerialPortIo_CommEvent(object sender, NativeSerialPort.CommOverlappedIo.CommEventArgs e)
 {
     if (IsDisposed || DataReceived == null && PinChanged == null) {
         m_CommEvent = 0;
         return;
     } else {
         lock (m_EventCheck) {
             m_CommEvent |= e.EventType;
         }
         CallEvent();
     }
 }
        /// <summary>
        /// Get the properties of the specified serial port.
        /// </summary>
        /// <remarks>
        /// If no instance to a NativeSerialPort is created, we instantiate a new one
        /// and get the properties. The port is closed afterwards.
        /// <para>If an instance to a NativeSerialPort exists, then the properties of the
        /// serial port are reread. If the port is open, it remains open, else the port
        /// is temporarily opened and then closed.</para>
        /// <para>Note, the windows feature RTS_CONTROL_TOGGLE is not supported by this class.</para>
        /// </remarks>
        /// <param name="port">The port to open.</param>
        private void GetPortSettings(string port)
        {
            bool setPort = false;

            if (m_SerialPort == null) {
                // We need to create a new instance. This is called from the constructor.
                if (port == null) {
                    m_SerialPort = new NativeSerialPort();

                    // Set the default properties of the DCB. We must do this here, so that
                    // this object has decent defaults, as we don't query the OS at all on
                    // what normal values should be.
                    BaudRate = 115200;
                    DataBits = 8;
                    Parity = Ports.Parity.None;
                    StopBits = Ports.StopBits.One;
                    Handshake = Ports.Handshake.None;
                    TxContinueOnXOff = false;
                    DiscardNull = false;
                    XOnLimit = 2048;
                    XOffLimit = 512;
                    ParityReplace = 0;
                } else {
                    try {
                        m_SerialPort = new NativeSerialPort(port);
                        m_SerialPort.SerialPortCommState.GetCommState();
                        m_SerialPort.SerialPortCommProperties.GetCommProperties();
                        m_SerialPort.SerialPortModemStatus.GetCommModemStatus();
                        m_SerialPort.Close();
                    } catch {
                        m_SerialPort = new NativeSerialPort();
                        m_SerialPort.Port = port;

                        BaudRate = 115200;
                        DataBits = 8;
                        Parity = Ports.Parity.None;
                        StopBits = Ports.StopBits.One;
                    }
                }

                m_BreakState = false;

                m_SerialPort.SerialPortIo.CommEvent += SerialPortIo_CommEvent;
                m_SerialPort.SerialPortIo.CommErrorEvent += SerialPortIo_CommErrorEvent;
            } else {
                if (m_SerialPort.IsOpen) {
                    if (port == null || m_SerialPort.Port == port) {
                        // Port is already open, no change in port specified, so just get the state
                        m_SerialPort.SerialPortCommState.GetCommState();
                        m_SerialPort.SerialPortCommProperties.GetCommProperties();
                        m_SerialPort.SerialPortModemStatus.GetCommModemStatus();
                        // The break state isn't affected here
                    } else {
                        // Port is already open, but port should change. Strange situation, probably
                        // not what is wanted, so ensure in the rest of the class this case is avoided.
                        m_SerialPort.Close();
                        m_SerialPort.Open(port);
                        m_SerialPort.SerialPortCommState.GetCommState();
                        m_SerialPort.SerialPortCommProperties.GetCommProperties();
                        m_SerialPort.SerialPortModemStatus.GetCommModemStatus();
                        if (m_BreakState) {
                            m_SerialPort.SerialPortModemStatus.SetCommBreak();
                        } else {
                            m_SerialPort.SerialPortModemStatus.ClearCommBreak();
                        }
                    }
                } else {
                    if (port == null || m_SerialPort.Port == port) {
                        // Port is not open, reopen it, get the state and close it again
                        m_SerialPort.Open();
                    } else {
                        // Port is not open, user wants to change the port. Get the state, close it
                        m_SerialPort.Open(port);
                    }
                    m_SerialPort.SerialPortCommState.GetCommState();
                    m_SerialPort.SerialPortCommProperties.GetCommProperties();
                    m_SerialPort.SerialPortModemStatus.GetCommModemStatus();
                    m_SerialPort.SerialPortModemStatus.ClearCommBreak();
                    m_BreakState = false;
                    m_SerialPort.Close();
                }
            }

            // Binary mode must always be set per MSDN
            m_SerialPort.SerialPortCommState.Binary = true;

            // Ensure the parity settings are consistent
            if (!m_SerialPort.SerialPortCommState.ParityEnable) {
                if (m_SerialPort.SerialPortCommState.Parity != Ports.Parity.None) {
                    m_SerialPort.SerialPortCommState.Parity = Ports.Parity.None;
                    setPort = true;
                }
            }

            // Get the Error Char. Only if it is zero and parity is enabled, we change it to 126
            // This is because the interface can't provide for an error char of zero and active.
            // This is a limitation of the API as taken over from the System.IO.Ports.SerialPort
            // implementation by Microsoft.
            m_ParityReplace = m_SerialPort.SerialPortCommState.ErrorChar;
            if (m_ParityReplace == 0 && m_SerialPort.SerialPortCommState.ErrorCharEnabled &&
                m_SerialPort.SerialPortCommState.ParityEnable && m_SerialPort.SerialPortCommState.Parity != Ports.Parity.None) {
                m_ParityReplace = 126;
            }

            // The function fAbortOnError should be disabled
            if (m_SerialPort.SerialPortCommState.AbortOnError) {
                m_SerialPort.SerialPortCommState.AbortOnError = false;
                setPort = true;
            }

            // Event and EOF chars, compatible with MS implementation
            if (m_SerialPort.SerialPortCommState.EventChar != 26) {
                m_SerialPort.SerialPortCommState.EventChar = 26;
                setPort = true;
            }
            if (m_SerialPort.SerialPortCommState.EofChar != 26) {
                m_SerialPort.SerialPortCommState.EofChar = 26;
                setPort = true;
            }

            // We don't support RTS_CONTROL_TOGGLE
            if (m_SerialPort.SerialPortCommState.RtsControl == NativeSerialPort.RtsControl.Toggle) {
                m_SerialPort.SerialPortCommState.RtsControl = NativeSerialPort.RtsControl.Disable;
                setPort = true;
            }

            // Set the XOn and XOff characters
            if (m_SerialPort.SerialPortCommState.XOnChar != 17) {
                m_SerialPort.SerialPortCommState.XOnChar = 17;
                setPort = true;
            }
            if (m_SerialPort.SerialPortCommState.XOffChar != 19) {
                m_SerialPort.SerialPortCommState.XOffChar = 19;
                setPort = true;
            }

            if (m_SerialPort.IsOpen && setPort) m_SerialPort.SerialPortCommState.SetCommState();
        }